From 46e4136eb0756774ee997507b96569c7fff5d506 Mon Sep 17 00:00:00 2001
From: lstrsrmn <alistair.sirman@gmail.com>
Date: Wed, 20 Oct 2021 22:29:04 +0100
Subject: [PATCH] finished it

---
 .idea/intellij-javadocs-4.0.1.xml        | 204 +++++++++++++++++++++++
 out/production/Space Cowboys/Test1.class | Bin 687 -> 0 bytes
 out/production/Space Cowboys/Test2.class | Bin 1256 -> 0 bytes
 src/Expression.java                      |  83 +++++++++
 src/Interpreter.java                     |  31 ++++
 src/Lexer.java                           |  74 ++++++++
 src/Pair.java                            |   9 +
 src/Parser.java                          |  97 +++++++++++
 src/ProgramHandler.java                  | 110 ++++++++++++
 src/Test1.java                           |   6 -
 src/Test2.java                           |  16 --
 src/Token.java                           |  12 ++
 src/program.bb                           |  13 ++
 13 files changed, 633 insertions(+), 22 deletions(-)
 create mode 100644 .idea/intellij-javadocs-4.0.1.xml
 delete mode 100644 out/production/Space Cowboys/Test1.class
 delete mode 100644 out/production/Space Cowboys/Test2.class
 create mode 100644 src/Expression.java
 create mode 100644 src/Interpreter.java
 create mode 100644 src/Lexer.java
 create mode 100644 src/Pair.java
 create mode 100644 src/Parser.java
 create mode 100644 src/ProgramHandler.java
 delete mode 100644 src/Test1.java
 delete mode 100644 src/Test2.java
 create mode 100644 src/Token.java
 create mode 100644 src/program.bb

diff --git a/.idea/intellij-javadocs-4.0.1.xml b/.idea/intellij-javadocs-4.0.1.xml
new file mode 100644
index 0000000..90d3347
--- /dev/null
+++ b/.idea/intellij-javadocs-4.0.1.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaDocConfiguration">
+    <GENERAL>
+      <MODE>UPDATE</MODE>
+      <OVERRIDDEN_METHODS>false</OVERRIDDEN_METHODS>
+      <SPLITTED_CLASS_NAME>true</SPLITTED_CLASS_NAME>
+      <LEVELS>
+        <LEVEL>FIELD</LEVEL>
+        <LEVEL>METHOD</LEVEL>
+        <LEVEL>TYPE</LEVEL>
+      </LEVELS>
+      <VISIBILITIES>
+        <VISIBILITY>PUBLIC</VISIBILITY>
+        <VISIBILITY>PROTECTED</VISIBILITY>
+        <VISIBILITY>DEFAULT</VISIBILITY>
+      </VISIBILITIES>
+    </GENERAL>
+    <TEMPLATES>
+      <CLASSES>
+        <CLASS>
+          <KEY>^.*(public|protected|private)*.+interface\s+\w+.*</KEY>
+          <VALUE>/**\n
+ * The interface ${name}.\n
+&lt;#if element.typeParameters?has_content&gt;        * \n
+&lt;/#if&gt;
+&lt;#list element.typeParameters as typeParameter&gt;
+        * @param &lt;${typeParameter.name}&gt; the type parameter\n
+&lt;/#list&gt;
+ */</VALUE>
+        </CLASS>
+        <CLASS>
+          <KEY>^.*(public|protected|private)*.+enum\s+\w+.*</KEY>
+          <VALUE>/**\n
+ * The enum ${name}.\n
+ */</VALUE>
+        </CLASS>
+        <CLASS>
+          <KEY>^.*(public|protected|private)*.+class\s+\w+.*</KEY>
+          <VALUE>/**\n
+ * The type ${name}.\n
+&lt;#if element.typeParameters?has_content&gt;        * \n
+&lt;/#if&gt;
+&lt;#list element.typeParameters as typeParameter&gt;
+        * @param &lt;${typeParameter.name}&gt; the type parameter\n
+&lt;/#list&gt;
+ */</VALUE>
+        </CLASS>
+        <CLASS>
+          <KEY>.+</KEY>
+          <VALUE>/**\n
+ * The type ${name}.\n
+ */</VALUE>
+        </CLASS>
+      </CLASSES>
+      <CONSTRUCTORS>
+        <CONSTRUCTOR>
+          <KEY>.+</KEY>
+          <VALUE>/**\n
+ * Instantiates a new ${name}.\n
+&lt;#if element.parameterList.parameters?has_content&gt;
+         *\n
+&lt;/#if&gt;
+&lt;#list element.parameterList.parameters as parameter&gt;
+         * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+&lt;/#list&gt;
+&lt;#if element.throwsList.referenceElements?has_content&gt;
+         *\n
+&lt;/#if&gt;
+&lt;#list element.throwsList.referenceElements as exception&gt;
+         * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+&lt;/#list&gt;
+ */</VALUE>
+        </CONSTRUCTOR>
+      </CONSTRUCTORS>
+      <METHODS>
+        <METHOD>
+          <KEY>^.*(public|protected|private)*\s*.*(\w(\s*&lt;.+&gt;)*)+\s+get\w+\s*\(.*\).+</KEY>
+          <VALUE>/**\n
+ * Gets ${partName}.\n
+&lt;#if element.typeParameters?has_content&gt;         * \n
+&lt;/#if&gt;
+&lt;#list element.typeParameters as typeParameter&gt;
+         * @param &lt;${typeParameter.name}&gt; the type parameter\n
+&lt;/#list&gt;
+&lt;#if element.parameterList.parameters?has_content&gt;
+         *\n
+&lt;/#if&gt;
+&lt;#list element.parameterList.parameters as parameter&gt;
+         * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+&lt;/#list&gt;
+&lt;#if isNotVoid&gt;
+         *\n
+         * @return the ${partName}\n
+&lt;/#if&gt;
+&lt;#if element.throwsList.referenceElements?has_content&gt;
+         *\n
+&lt;/#if&gt;
+&lt;#list element.throwsList.referenceElements as exception&gt;
+         * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+&lt;/#list&gt;
+ */</VALUE>
+        </METHOD>
+        <METHOD>
+          <KEY>^.*(public|protected|private)*\s*.*(void|\w(\s*&lt;.+&gt;)*)+\s+set\w+\s*\(.*\).+</KEY>
+          <VALUE>/**\n
+ * Sets ${partName}.\n
+&lt;#if element.typeParameters?has_content&gt;         * \n
+&lt;/#if&gt;
+&lt;#list element.typeParameters as typeParameter&gt;
+         * @param &lt;${typeParameter.name}&gt; the type parameter\n
+&lt;/#list&gt;
+&lt;#if element.parameterList.parameters?has_content&gt;
+         *\n
+&lt;/#if&gt;
+&lt;#list element.parameterList.parameters as parameter&gt;
+         * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+&lt;/#list&gt;
+&lt;#if isNotVoid&gt;
+         *\n
+         * @return the ${partName}\n
+&lt;/#if&gt;
+&lt;#if element.throwsList.referenceElements?has_content&gt;
+         *\n
+&lt;/#if&gt;
+&lt;#list element.throwsList.referenceElements as exception&gt;
+         * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+&lt;/#list&gt;
+ */</VALUE>
+        </METHOD>
+        <METHOD>
+          <KEY>^.*((public\s+static)|(static\s+public))\s+void\s+main\s*\(\s*String\s*(\[\s*\]|\.\.\.)\s+\w+\s*\).+</KEY>
+          <VALUE>/**\n
+ * The entry point of application.\n
+
+     &lt;#if element.parameterList.parameters?has_content&gt;
+         *\n
+&lt;/#if&gt;
+     * @param ${element.parameterList.parameters[0].name} the input arguments\n
+&lt;#if element.throwsList.referenceElements?has_content&gt;
+         *\n
+&lt;/#if&gt;
+&lt;#list element.throwsList.referenceElements as exception&gt;
+         * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+&lt;/#list&gt;
+ */</VALUE>
+        </METHOD>
+        <METHOD>
+          <KEY>.+</KEY>
+          <VALUE>/**\n
+ * ${name}&lt;#if isNotVoid&gt; ${return}&lt;/#if&gt;.\n
+&lt;#if element.typeParameters?has_content&gt;         * \n
+&lt;/#if&gt;
+&lt;#list element.typeParameters as typeParameter&gt;
+         * @param &lt;${typeParameter.name}&gt; the type parameter\n
+&lt;/#list&gt;
+&lt;#if element.parameterList.parameters?has_content&gt;
+         *\n
+&lt;/#if&gt;
+&lt;#list element.parameterList.parameters as parameter&gt;
+         * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+&lt;/#list&gt;
+&lt;#if isNotVoid&gt;
+         *\n
+         * @return the ${return}\n
+&lt;/#if&gt;
+&lt;#if element.throwsList.referenceElements?has_content&gt;
+         *\n
+&lt;/#if&gt;
+&lt;#list element.throwsList.referenceElements as exception&gt;
+         * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+&lt;/#list&gt;
+ */</VALUE>
+        </METHOD>
+      </METHODS>
+      <FIELDS>
+        <FIELD>
+          <KEY>^.*(public|protected|private)*.+static.*(\w\s\w)+.+</KEY>
+          <VALUE>/**\n
+ * The constant ${element.getName()}.\n
+ */</VALUE>
+        </FIELD>
+        <FIELD>
+          <KEY>^.*(public|protected|private)*.*(\w\s\w)+.+</KEY>
+          <VALUE>/**\n
+    &lt;#if element.parent.isInterface()&gt;
+        * The constant ${element.getName()}.\n
+&lt;#else&gt;
+        * The ${name}.\n
+&lt;/#if&gt; */</VALUE>
+        </FIELD>
+        <FIELD>
+          <KEY>.+</KEY>
+          <VALUE>/**\n
+    &lt;#if element.parent.isEnum()&gt;
+        *${name} ${typeName}.\n
+&lt;#else&gt;
+        * The ${name}.\n
+&lt;/#if&gt;*/</VALUE>
+        </FIELD>
+      </FIELDS>
+    </TEMPLATES>
+  </component>
+</project>
\ No newline at end of file
diff --git a/out/production/Space Cowboys/Test1.class b/out/production/Space Cowboys/Test1.class
deleted file mode 100644
index eae931181a00a1762e70d2f399d3cfaff1a0aa32..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 687
zcmX^0Z`VEs1_oOO11<(824;2!79Ivx1~x_pfvm)`ME#t^ymWp4q^#8B5=I6#o6Nk-
z5<5l)W)00Sb_Nbc2G)?&;u0ec1};Vh=ES6AE(Uf69*}-sMh0;WPfs6&8Nnq*nR)5f
znqiy_{0su@41zoiLJYzv)&y4;m!#%0GBD?tmM}7iLNsUQ>jxBN=9L7O6s0EST7zs5
z<zWzG5NBjyEdWU{GKgqsLezpC3$=)gL6Sj=ok5z1L54w=kwF;j5>&$&8Q8%l<m53j
zh-zRO0rI0fBZCxJE7<Iy(!7$)+*H?!<kW(a%=|nq202iWDM16mkdcAKIX@+pk%8YQ
zGcVPzG&d==C?qi{CzX*w$R|HJF()jsC=<ko3bK@BWEL|ru={|5(a@Tafh9LFGmnu$
zOd}eba~K&|5{uG{85xAJNHa39l%y7yz)Ul;W@O+B&Mz%WPIb!!Ie-gnhaSi?42lej
z3``6lz{J1^if#r*24w~Y27Lxb21W)323D=@42&BY7#NrsR2Uc-*ua8}45|za3_M^q
zD}x$?Is*d(CxZrqCRB4211s22x!nxxku0o2oZA_=eKs-hX>Vf?*~TETn?WveJA=Z0
sxT$;$%nS?+%nUpXEDT}{>|oQyASN(qF=&JB5@OI{&;>h653Elg0CZ`NvH$=8

diff --git a/out/production/Space Cowboys/Test2.class b/out/production/Space Cowboys/Test2.class
deleted file mode 100644
index 27388d7eee6087756af0511f757d52fa34b03c49..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1256
zcmX^0Z`VEs1_oOOH!cPy24;2!79Ivx1~x_pfvm)`ME#t^ymWp4q^#8B5=I6#o6Nk-
z5<5l)W)00SP6iGJPId+^9tLg(9!3V%kksN5BSr?s3PuJ-Pmm-Z4+B3)hOrXF6XanK
zVi0CzV60+f5b{Bo9b8hBnU`)Y#K6EH%EKVWAkN4jo|~AR>YSgKoLCZ`S(4$LpI2Ox
zm{(HF$e^L&>4~XV6H|zjL6Sj=ok5z1L54vV#V^5?#U-h^j10`FMMaDZq7bc_`T7Ax
znRz9_B}J);xz<7qj12N1$0#r|h-!FZF`tV;i9wm2L4}7wl|hY>K^W{GR8trk*b6{r
z=H!74f!G5MO{kAG!x$OFvHK^Ck%7fIKP8osf!`-HFV(L!Hz~C!Brz!`6%=;)$%#2(
ziA9+pK2(sUBqOt!k%8R@90}Hp42+4442(&P42;Q)46I;hFfxc}VDShe18ZtgQGO94
z16Oc<X;E^jTPDaBF0es*Aa5};2sq{EmlT&2B^LOmmSp6o6!Wt&m~$~$Fj%rPSb>7c
znvp>Tq!f}`GV{vvvs3jU-h@P>TViraeo-YO!we0ifPgB580wLjmy(lOtm2cOpIusD
zjid}>5V8o0#*oT_RAfo0@@OOzAnDf{+51o<oD*|$f-_4}tvMKM85!6Z6&Mv17&#d1
z85!70Qj1Fz7#SIOJoEBWi=1;3i;Gi>*%_P|8B{U+ip>k`3@(fea`=@pGO$7X%b>`>
z!NA18z`)GF0Lo7cAi&SS1EN6r1}wwKz{;S`z{sG%z`&5hz{J49z`!7)wVi=cOL{8<
zyOzvW23{@QtqcMi85kIt7&I9e7{nM@85kH?8CV$D7&sZ&8Tc4D7=#%(8MGJ}7_=bz
z8MGO6z_y4m=rZsyFoMiv&|}~MyGDdTpFx;`nSqhPfWZ)IvkjQfz#ycxg@Ijb3j?p#
z76yS`3?d8+8{qb`fz9Ct+XFFE2x<=_gAoHr7UTyz1}3mNflUk&Aj5Vs$T2W%V^Bo6
zA5<hUFz_+(Gw>ssB>**xnZX!rqX~m414tDUgBb%OgAJIpV{l+#VBlh4WN>6~W^iSY
F1OSWl6SM#T

diff --git a/src/Expression.java b/src/Expression.java
new file mode 100644
index 0000000..68630f1
--- /dev/null
+++ b/src/Expression.java
@@ -0,0 +1,83 @@
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class Expression {
+    public interface Value<T> {
+        public T getValue();
+    }
+
+    static class IntVal implements Value<Integer> {
+        Integer v;
+
+        public IntVal(Integer v) {
+            this.v = v;
+        }
+        public Integer getValue() {
+            return v;
+        }
+    }
+
+    static class BoolValue implements Value<Boolean> {
+        boolean b;
+
+        public BoolValue(boolean b) {
+            this.b = b;
+        }
+
+        public Boolean getValue() {
+            return b;
+        }
+    }
+
+    interface Expr {
+        Value run(ProgramHandler.ProgramState s);
+    }
+
+    public static class LiteralExpr implements Expr {
+        Value x;
+
+        @Override
+        public Value run(ProgramHandler.ProgramState s) {
+            return x;
+        }
+
+        public LiteralExpr(Value x) {
+            this.x = x;
+        }
+    }
+
+    static class VarExpr implements Expr {
+        String name;
+
+        @Override
+        public Value run(ProgramHandler.ProgramState s) {
+            return new IntVal(s.varLookup.get(name));
+        }
+
+        public VarExpr(String n) {
+            name = n;
+        }
+    }
+
+    static class NotExpr implements Expr {
+        Expr lhs, rhs;
+
+        public NotExpr(Expr lhs, Expr rhs) {
+            this.lhs = lhs;
+            this.rhs = rhs;
+        }
+        public Value run(ProgramHandler.ProgramState s) {
+            Value lhsV = lhs.run(s);
+            Value rhsV = rhs.run(s);
+            if (lhsV.getClass() == rhsV.getClass()) {
+                return new BoolValue(lhsV.getValue() == rhsV.getValue());
+            }
+            return new BoolValue(false);
+        }
+    }
+
+    public static class ExpressionBuilder {
+        List<Expr> x = new ArrayList<Expr>();
+    }
+}
diff --git a/src/Interpreter.java b/src/Interpreter.java
new file mode 100644
index 0000000..577c933
--- /dev/null
+++ b/src/Interpreter.java
@@ -0,0 +1,31 @@
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.*;
+
+public class Interpreter {
+    public static void main(String[] args) {
+        try {
+            // reading the file
+            File filePath = new File("C:\\Users\\alist\\IdeaProjects\\Space Cowboys\\src\\program.bb");
+            Scanner reader = new Scanner(filePath);
+            StringBuilder data = new StringBuilder();
+            // moves the file into a string
+            while (reader.hasNextLine()) {
+                data.append(reader.nextLine());
+                data.append(" ");
+            }
+            reader.close();
+            Lexer.LexerContainer container = Lexer.lexer(data.toString().trim().replaceAll(" +", " "));
+            ProgramHandler.ProgramState state = new ProgramHandler.ProgramState();
+            ProgramHandler.Program program = Parser.parse(container);
+            program.run(state);
+            for (Map.Entry<String, Integer> entry : state.varLookup.entrySet()) {
+                System.out.println("Variable: " + entry.getKey() + ", Value: " + entry.getValue());
+            }
+        }
+        catch (FileNotFoundException e){
+            System.out.println("File can't be found.");
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/src/Lexer.java b/src/Lexer.java
new file mode 100644
index 0000000..d588bd6
--- /dev/null
+++ b/src/Lexer.java
@@ -0,0 +1,74 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class Lexer {
+
+    public static class LexerContainer {
+        public List<Token> tokens;
+        List<String> vars;
+        public LexerContainer(List<Token> tokens, List<String> vars) {
+            this.tokens = tokens;
+            this.vars = vars;
+        }
+    }
+
+    /**
+     * @param file the file to be processed
+     * @return list of tokens produced by the lexer
+     */
+    public static LexerContainer lexer(String file) {
+        List<Token> tokens = new ArrayList<Token>();
+        List<String> vars = new ArrayList<>();
+        int previousChar = 0;
+        for (int currentChar = 0; currentChar < file.length(); currentChar++) {
+            if (file.charAt(currentChar) == ' ' || file.charAt(currentChar) == ';') {
+                String x = "";
+                if (previousChar == currentChar) {
+                    x = "" + file.charAt(previousChar);
+                }
+                else {
+                    x = file.substring(previousChar, currentChar).replaceAll(" ", "");
+                }
+                switch (x) {
+                    case ("clear") -> {
+                        tokens.add(Token.Clear);
+                    }
+                    case ("incr") -> {
+                        tokens.add(Token.Incr);
+                    }
+                    case ("decr") -> {
+                        tokens.add(Token.Decr);
+                    }
+                    case ("while") -> {
+                        tokens.add(Token.While);
+                    }
+                    case ("do") -> {
+                        tokens.add(Token.Do);
+                    }
+                    case ("not") -> {
+                        tokens.add(Token.Not);
+                    }
+                    case (";") -> {
+                        tokens.add(Token.SemiColon);
+                    }
+                    case ("end") -> {
+                        tokens.add(Token.End);
+                    }
+                    default -> {
+                        if (x.matches("[0-9]+")) {
+                            tokens.add(Token.Number);
+                            vars.add(x);
+                        }
+                        else if (x.matches("[a-zA-Z]+")) {
+                            tokens.add(Token.Var);
+                            vars.add(x);
+                        }
+                    }
+                }
+                previousChar = currentChar;
+            }
+        }
+        return new LexerContainer(tokens, vars);
+    }
+}
diff --git a/src/Pair.java b/src/Pair.java
new file mode 100644
index 0000000..1a10efc
--- /dev/null
+++ b/src/Pair.java
@@ -0,0 +1,9 @@
+public class Pair<T, K> {
+    T first;
+    K second;
+
+    public Pair(T t, K k) {
+        first = t;
+        second = k;
+    }
+}
diff --git a/src/Parser.java b/src/Parser.java
new file mode 100644
index 0000000..c3a1e9d
--- /dev/null
+++ b/src/Parser.java
@@ -0,0 +1,97 @@
+import java.util.List;
+
+public class Parser {
+    public static ProgramHandler.Program parse(Lexer.LexerContainer container) {
+        List<Token> tokens = container.tokens;
+        List<String> vars = container.vars;
+
+        ProgramHandler.Program program = new ProgramHandler.Program();
+
+        while (!tokens.isEmpty()) {
+            Token token = tokens.remove(0);
+            if (token != Token.SemiColon) {
+                switch (token) {
+                    case Clear -> {
+                        if (tokens.remove(0) == Token.Var) {
+                            ProgramHandler.ClearStatement statement = new ProgramHandler.ClearStatement();
+                            statement.v = new ProgramHandler.Variable(vars.remove(0));
+                            program.stmts.add(statement);
+                        } else {
+                            System.err.println("Clear not followed by variable");
+                        }
+                    }
+                    case Incr -> {
+                        if (tokens.remove(0) == Token.Var) {
+                            ProgramHandler.IncrStatement statement = new ProgramHandler.IncrStatement();
+                            statement.v = new ProgramHandler.Variable(vars.remove(0));
+                            program.stmts.add(statement);
+                        } else {
+                            System.err.println("Incr not followed by variable");
+                        }
+                    }
+                    case Decr -> {
+                        if (tokens.remove(0) == Token.Var) {
+                            ProgramHandler.DecrStatement statement = new ProgramHandler.DecrStatement();
+                            statement.v = new ProgramHandler.Variable(vars.remove(0));
+                            program.stmts.add(statement);
+                        } else {
+                            System.err.println("Decr not followed by variable");
+                        }
+                    }
+                    case While -> {
+                        ProgramHandler.WhileLoop loop = new ProgramHandler.WhileLoop();
+                        Expression.Expr expr = eParse(container);
+                        loop.expr = expr;
+                        loop.p = parse(container);
+                        program.stmts.add(loop);
+                    }
+                    case End -> {
+                        return program;
+                    }
+                    case Var, Number -> {
+                        System.err.println("Something went wrong, L for u. " + token + " " + tokens.get(0));
+                    }
+                }
+            }
+        }
+
+        return program;
+    }
+
+    private static Expression.Expr eParse(Lexer.LexerContainer container){
+        List<Token> tokens = container.tokens;
+        List<String> vars = container.vars;
+        Expression.Expr e = null;
+
+        while (!tokens.isEmpty()) {
+            Token token = tokens.remove(0);
+            switch (token) {
+                case Var -> {
+                    if (e == null) {
+                        e = new Expression.VarExpr(vars.remove(0));
+                    } else {
+                        System.err.println("Expression not valid");
+                        System.exit(1);
+                    }
+                } case Number -> {
+                    if (e == null) {
+                        e = new Expression.LiteralExpr(new Expression.IntVal(Integer.parseInt(vars.remove(0))));
+                    } else {
+                        System.err.println("Expression not valid");
+                        System.exit(1);
+                    }
+                } case Not -> {
+                    if (e != null) {
+                        Expression.Expr rhs = eParse(container);
+                        e = new Expression.NotExpr(e, rhs);
+                    }
+                } case Do, End, SemiColon -> {
+                    return e;
+                }
+            }
+        }
+        System.err.println("Expr never ended");
+        System.exit(1);
+        return new Expression.LiteralExpr(new Expression.IntVal(1));
+    }
+}
diff --git a/src/ProgramHandler.java b/src/ProgramHandler.java
new file mode 100644
index 0000000..fbd7b8d
--- /dev/null
+++ b/src/ProgramHandler.java
@@ -0,0 +1,110 @@
+import java.util.*;
+
+public class ProgramHandler {
+    private static ProgramHandler single_instance = null;
+
+    private ProgramHandler() {
+    }
+
+    public static class Variable {
+        String name;
+
+        Variable(String n) {
+            name = n;
+        }
+    }
+
+    public static ProgramHandler getInstance() {
+        if (single_instance == null)
+            single_instance = new ProgramHandler();
+
+        return single_instance;
+    }
+
+    interface Runnable {
+        public void run(ProgramState state);
+    }
+
+    static class Statement implements Runnable {
+        @Override
+        public void run(ProgramState state) {
+
+        }
+    }
+
+    static class ProgramState {
+        public HashMap<String, Integer> varLookup = new HashMap<>();
+
+        public HashMap<String, Integer> getState() {
+            return varLookup;
+        }
+    }
+
+    static class Program implements Runnable {
+        public List<Statement> stmts = new ArrayList<Statement>();
+
+        @Override
+        public void run(ProgramState state) {
+            for (Statement statement : stmts) {
+                statement.run(state);
+            }
+        }
+    }
+
+    static class ClearStatement extends Statement {
+        public Variable v;
+
+        @Override
+        public void run(ProgramState state) {
+            if (!state.varLookup.containsKey(v.name)) {
+                state.varLookup.put(v.name, 0);
+            } else {
+                state.varLookup.replace(v.name, 0);
+            }
+        }
+    }
+
+    static class IncrStatement extends Statement {
+        public Variable v;
+
+        @Override
+        public void run(ProgramState state) {
+            if (state.varLookup.containsKey(v.name)) {
+                int curr = state.varLookup.get(v.name);
+                state.varLookup.replace(v.name, curr + 1);
+            }
+        }
+    }
+
+    static class DecrStatement extends Statement {
+        public Variable v;
+
+        @Override
+        public void run(ProgramState state) {
+            if (state.varLookup.containsKey(v.name)) {
+                int curr = state.varLookup.get(v.name);
+                state.varLookup.replace(v.name, curr - 1);
+            }
+        }
+    }
+
+    static class WhileLoop extends Statement {
+        public Program p;
+        public Expression.Expr expr;
+
+        @Override
+        public void run(ProgramState state) {
+            Expression.Value val = expr.run(state);
+            Expression.BoolValue boolValue = val instanceof Expression.BoolValue ? ((Expression.BoolValue) val) : null;
+            if (boolValue != null) {
+                if (!boolValue.b) {
+                    p.run(state);
+                    run(state);
+                }
+            } else {
+                System.err.println("Wrong Expression Type");
+            }
+        }
+
+    }
+}
diff --git a/src/Test1.java b/src/Test1.java
deleted file mode 100644
index d6a891d..0000000
--- a/src/Test1.java
+++ /dev/null
@@ -1,6 +0,0 @@
-public class Test1 {
-    public static void main(String[] args) {
-        Test2 test = new Test2(1, 2, "abc");
-        System.out.println(test.print());
-    }
-}
diff --git a/src/Test2.java b/src/Test2.java
deleted file mode 100644
index 0ff8da2..0000000
--- a/src/Test2.java
+++ /dev/null
@@ -1,16 +0,0 @@
-public class Test2 {
-    int x;
-    int y;
-    String z;
-    public Test2(int a, int b, String c) {
-        x = a;
-        y = b;
-        z = c;
-    }
-    public String print() {
-        return x + " " + y + " " + " " + z;
-    }
-    public void error() {
-        java.lang.System.err.println("test " + x);
-    }
-}
diff --git a/src/Token.java b/src/Token.java
new file mode 100644
index 0000000..d715d49
--- /dev/null
+++ b/src/Token.java
@@ -0,0 +1,12 @@
+public enum Token {
+    Clear,
+    Incr,
+    Decr,
+    While,
+    Do,
+    Not,
+    Var,
+    SemiColon,
+    Number,
+    End
+}
\ No newline at end of file
diff --git a/src/program.bb b/src/program.bb
new file mode 100644
index 0000000..d088686
--- /dev/null
+++ b/src/program.bb
@@ -0,0 +1,13 @@
+clear X;
+clear Y;
+incr Y;
+clear jakub;
+while jakub not 7 do;
+    incr jakub;
+end;
+incr X;
+incr X;
+incr X;
+while X not 0 do;
+   decr X;
+end;
\ No newline at end of file
-- 
GitLab