public void forLoop2()
        {
            EOrientation orientation = EOrientation.East;
            Robot robot = Robot.Create (orientation, new Map(EDifficulty.Easy));

            MainCode mainCode = new MainCode ();

            // Create (int i = 1; i < 5; i*i)

            //Create i
            ConcreteVariable iVar = new ConcreteVariable (new Variable (1, EVariableType.Int));
            DefineVariable iDefine = new DefineVariable (iVar);
            CmdDefineVariable iDefineCommand = new CmdDefineVariable ("i", iDefine);

            //create a variable thats always 2
            Variable staticTwoVar = new Variable (2, EVariableType.Int);
            VariableSolver staticTwoVarS = new ConcreteVariable (staticTwoVar);

            // Create i*i
            ConcreteVariable iGather = new ConcreteVariable ("i"); // Gathers i, this creates a reference to iVar
            VariableSolver ixiSolver = new VariableCombo (iGather, staticTwoVarS, EMathOperator.Multiply);
            DefineVariable ixiDefine = new DefineVariable (ixiSolver);
            CmdDefineVariable ixiSolverCommand = new CmdDefineVariable ("i", ixiDefine);

            //create a variable thats always 5
            Variable max = new Variable (5, EVariableType.Int);
            VariableSolver maxS = new ConcreteVariable (max);

            //Create i < 4
            ValueSolver solver = new ValueSolver (iGather, maxS, EComparisonOperator.ValueLessThan);

            ForLoop forLoop = new ForLoop (solver, iDefineCommand, ixiSolverCommand);

            //forLoop.variables["i"] = new Variable(1, EVariableType.Int);

            mainCode.addChild (forLoop);
            forLoop.addChild (new TurnRight ());

            mainCode.execute ();

            EOrientation actual = robot.orientationEnum;
            EOrientation expected = EOrientation.North;
            Assert.AreEqual (expected, actual);
        }
        public void forLoop1()
        {
            EOrientation orientation = EOrientation.East;
            Robot robot = Robot.Create (orientation, new Map(EDifficulty.Easy));

            MainCode mainCode = new MainCode ();

            // Create (int i = 0; i < 5; i++)

            //Create i
            ConcreteVariable iVar = new ConcreteVariable (new Variable (0, EVariableType.Int));
            DefineVariable iDefine = new DefineVariable (iVar);
            CmdDefineVariable iDefineCommand = new CmdDefineVariable ("i", iDefine);

            //create a variable thats always 5
            Variable max = new Variable (5, EVariableType.Int);
            VariableSolver maxS = new ConcreteVariable (max);

            //Create i < 5
            ValueSolver solver = new ValueSolver (iVar, maxS, EComparisonOperator.ValueLessThan);

            // Create i++
            ConcreteVariable staticOneVar = new ConcreteVariable (new Variable (1, EVariableType.Int));
            ConcreteVariable iGather = new ConcreteVariable ("i"); // Gathers i, this creates a reference to iVar
            VariableSolver iPlusOneSolver = new VariableCombo (iGather, staticOneVar, EMathOperator.Add);
            DefineVariable iPlusOneDefine = new DefineVariable (iPlusOneSolver);
            CmdDefineVariable iPlusOneSolverCommand = new CmdDefineVariable ("i", iPlusOneDefine);

            Composite forLoop = new ForLoop (solver, iDefineCommand, iPlusOneSolverCommand);

            mainCode.addChild (forLoop);
            forLoop.addChild (new TurnRight ());

            mainCode.execute ();

            EOrientation actual = robot.orientationEnum;
            EOrientation expected = EOrientation.South;
            Assert.AreEqual (expected, actual);
        }
        /// Author: Max Hamulyak
        /// Date:	24-06-2015
        /// <summary>
        /// Builds the I assignment.
        /// </summary>
        /// <returns>The I assignment.</returns>
        /// <param name="tokens">Tokens.</param>
        /// <param name="currentLine">Current line.</param>
        protected VariableSolver BuildIAssignment(List<Token> tokens, int currentLine)
        {
            if (tokens.Count > 0) {
                int i = 0;
                List<IAssignment> assignments = new List<IAssignment> ();
                while (i < tokens.Count) {

                    Token tokenAtIndex = tokens.ElementAt (i);

                    if (tokenAtIndex.Type == ETokenType.VARIABLE) {
                        ConcreteVariable variable = new ConcreteVariable(tokenAtIndex.Value);
                        variable.LineNumber = currentLine;
                        assignments.Add (variable);
                    } else if (tokenAtIndex.Type == ETokenType.Operator) {

                        EMathOperator myEMathOperator = ParseMathOperatorFromToken (tokenAtIndex);
                        assignments.Add (new MathOperator (myEMathOperator));
                    } else if (tokenAtIndex.Type == ETokenType.Literal) {
                        bool boolValue;
                        int intValue;
                        Variable v = null;
                        if (Boolean.TryParse (tokenAtIndex.Value, out boolValue)) {
                            v = new Variable (boolValue, EVariableType.Bool);
                        } else if (int.TryParse (tokenAtIndex.Value, out intValue)) {
                            v = new Variable (intValue, EVariableType.Int);
                        } else {
                            v = new Variable (tokenAtIndex.Value.TrimStart('"').TrimEnd('"'), EVariableType.String);
                        }
                        ConcreteVariable variable = new ConcreteVariable (v);
                        variable.LineNumber = currentLine;
                        assignments.Add (variable);
                    }
                    i++;
                }
                return BuildDefineVariable (assignments, EMathOperator.Multiply);
            } else {
                throw EmptyIAssignment (currentLine);
            }
        }
        /// Author: Max Hamulyak
        /// Date: 26-06-2015
        /// <summary>
        /// Parses for loop header, and finds start and ending value of the regex, in doing this it build a tuple that
        /// can be used in the creation of the forloop codeblock.
        /// </summary>
        /// <returns>The for loop header.</returns>
        /// <param name="headerDeclaration">Header declaration.</param>
        /// <param name="headerLineNumber">Header line number.</param>
        protected override Tuple<Solver, CmdDefineVariable, CmdDefineVariable> ParseForLoopHeader(List<Token> headerDeclaration, int headerLineNumber)
        {
            if (headerDeclaration.Count == 3 && headerDeclaration [0].Type == ETokenType.FOR && headerDeclaration [1].Type == ETokenType.startBlock && headerDeclaration[2].Type == ETokenType.EOL) {
                Token t = headerDeclaration.First ();
                List<String> result = new List<string> ();
                GroupCollection groups = forLoopRegex.Match (t.Value).Groups;
                if (groups.Count > 1) {
                    foreach (var item in forLoopRegex.GetGroupNames()) {
                        result.Add (string.Format ("Group: {0}, Value: {1}", item, groups [item].Value));
                    }
                    int startValue;
                    int endValue;
                    int.TryParse (groups ["startingLow"].Value, out startValue);
                    int.TryParse (groups ["endingHigh"].Value, out endValue);

                    string varName = groups ["loopIndex"].Value;
                    VariableSolver a = new ConcreteVariable (varName);
                    VariableSolver b = new ConcreteVariable (new Variable (1, EVariableType.Int));
                    VariableSolver c = new ConcreteVariable (new Variable (endValue, EVariableType.Int));
                    CmdDefineVariable defineLoopVar = new CmdDefineVariable (varName, new DefineVariable (new ConcreteVariable (new Variable (startValue, EVariableType.Int))));
                    CmdDefineVariable incrementVar = new CmdDefineVariable (varName, new DefineVariable (new VariableCombo (a, b, EMathOperator.Add)));
                    ValueSolver vs = new ValueSolver (a, c, EComparisonOperator.ValueLessThan);

                    return new Tuple<Solver, CmdDefineVariable, CmdDefineVariable> (vs, defineLoopVar, incrementVar);
                } else {
                    throw IncompleteDeclarationOfCondition (headerLineNumber, ETokenType.FOR, forLoopStatementIndicatorValue);
                }
            } else {
                Token startOfForBlock = headerDeclaration.FirstOrDefault (forLoopStatementStartBlockIndicator);
                if (startOfForBlock == null) {
                    if (headerDeclaration.Exists (x => x.Type == ETokenType.CommentLine)) {
                        throw CommentInsideCondition (headerLineNumber, ETokenType.FOR, ":");
                    } else {
                        throw IncompleteDeclarationOfCondition (headerLineNumber, ETokenType.FOR, ":");
                    }
                } else {
                    int startOfBlockIndex = headerDeclaration.IndexOf (startOfForBlock);
                    //First token indicates this should be WHILE Loop, so it can be skipped
                    List<Token> tokensTillRange = headerDeclaration.GetRange (1, startOfBlockIndex - 1);
                    if (startOfBlockIndex + 2 < headerDeclaration.Count) {
                        List<Token> tokensAfterRange = headerDeclaration.GetRange (startOfBlockIndex + 1, headerDeclaration.Count - startOfBlockIndex - 1);
                        tokensAfterRange.RemoveAll (x => x.Type == ETokenType.WhiteSpace || x.Type == ETokenType.CommentLine || x.Type == ETokenType.EOL);
                        if (tokensAfterRange.Count > 0) {
                            Token errorToken = tokensAfterRange.First ();
                            if (errorToken.Type == ETokenType.VARIABLE || errorToken.Type == ETokenType.Literal || errorToken.Type == ETokenType.FUNCTIONCall) {
                                throw ValueIndicatorAfterCondition (headerLineNumber, ETokenType.FOR, errorToken.Type, errorToken.Value);
                            } else {
                                throw BlockIndicatorAfterCondition (headerLineNumber, ETokenType.FOR, errorToken.Type);
                            }
                        }
                    }
                    tokensTillRange.RemoveAll (x => x.Type == ETokenType.WhiteSpace);
                    if (tokensTillRange.Count > 0) {
                        Token rangeToken = tokensTillRange.FirstOrDefault (x => x.Type == ETokenType.PythonRange);
                        Token variableToken = tokensTillRange.FirstOrDefault (x => x.Type == ETokenType.VARIABLE);
                        Token keyWordToken = tokensTillRange.FirstOrDefault (x => x.Type == ETokenType.KeyWord);
                        tokensTillRange.Remove (rangeToken);
                        tokensTillRange.Remove (variableToken);
                        tokensTillRange.Remove (keyWordToken);

                        if (tokensTillRange.Count > 0) {
                            Token errorToken = tokensTillRange.First ();
                            if (errorToken.Type == ETokenType.VARIABLE || errorToken.Type == ETokenType.Literal || errorToken.Type == ETokenType.FUNCTIONCall) {
                                throw ValueIndicatorInsideCondition (headerLineNumber, ETokenType.FOR, errorToken.Type, errorToken.Value);
                            } else {
                                throw BlockIndicatorInsideCondition (headerLineNumber, ETokenType.FOR, errorToken.Type);
                            }
                        } else {
                            string tokenValue = rangeToken.Value;
                            int leftIndex = tokenValue.IndexOf ("(");
                            tokenValue = tokenValue.Remove (0, leftIndex + 1).TrimEnd (')');
                            string[] splitValues = tokenValue.Split (",".ToCharArray (), 2);
                            int startIndex = -1;
                            int maxIndex = -1;
                            int.TryParse (splitValues [0], out startIndex);
                            int.TryParse (splitValues [1], out maxIndex);
                            string varName = variableToken.Value;
                            VariableSolver a = new ConcreteVariable (varName);
                            VariableSolver b = new ConcreteVariable (new Variable (1, EVariableType.Int));
                            VariableSolver c = new ConcreteVariable (new Variable (maxIndex, EVariableType.Int));
                            CmdDefineVariable defineLoopVar = new CmdDefineVariable (varName, new DefineVariable (new ConcreteVariable (new Variable (startIndex, EVariableType.Int))));
                            CmdDefineVariable incrementVar = new CmdDefineVariable (varName, new DefineVariable (new VariableCombo (a, b, EMathOperator.Add)));
                            ValueSolver vs = new ValueSolver (a, c, EComparisonOperator.ValueLessThan);

                            return new Tuple<Solver, CmdDefineVariable, CmdDefineVariable> (vs, defineLoopVar, incrementVar);
                        }
                    } else {
                        throw EmptyCondition (headerLineNumber, ETokenType.FOR, ":");
                    }
                }
            }
        }
        public void variableStringSubstract()
        {
            MainCode mainCode = new MainCode ();

            // create i = 10
            ConcreteVariable iVar = new ConcreteVariable (new Variable ("10", EVariableType.String));
            DefineVariable iDefine = new DefineVariable (iVar);
            CmdDefineVariable iDefineCommand = new CmdDefineVariable ("i", iDefine);

            // create x = 5;
            ConcreteVariable xVar = new ConcreteVariable (new Variable (5, EVariableType.Int));
            DefineVariable xDefine = new DefineVariable (xVar);
            CmdDefineVariable xDefineCommand = new CmdDefineVariable ("x", xDefine);

            // Gather the variables
            ConcreteVariable iGather = new ConcreteVariable ("i");
            ConcreteVariable xGather = new ConcreteVariable ("x");

            // calculate and put the values in ii
            VariableSolver calculation = new VariableCombo (iGather, xGather, EMathOperator.Subtract);
            DefineVariable calcCommand = new DefineVariable (calculation);
            CmdDefineVariable executeCalculation = new CmdDefineVariable ("ii", calcCommand);

            mainCode.addChild (xDefineCommand);
            mainCode.addChild (iDefineCommand);
            mainCode.addChild (executeCalculation);
            mainCode.execute ();

            //ConcreteVariable iiGather = new ConcreteVariable ("ii");
        }
        public void variableStringAdd()
        {
            MainCode mainCode = new MainCode ();

            // create i = 10
            ConcreteVariable iVar = new ConcreteVariable (new Variable ("10", EVariableType.String));
            DefineVariable iDefine = new DefineVariable (iVar);
            CmdDefineVariable iDefineCommand = new CmdDefineVariable ("i", iDefine);

            // create x = 5;
            ConcreteVariable xVar = new ConcreteVariable (new Variable (5, EVariableType.Int));
            DefineVariable xDefine = new DefineVariable (xVar);
            CmdDefineVariable xDefineCommand = new CmdDefineVariable ("x", xDefine);

            // Gather the variables
            ConcreteVariable iGather = new ConcreteVariable ("i");
            ConcreteVariable xGather = new ConcreteVariable ("x");

            // calculate and put the values in ii
            VariableSolver calculation = new VariableCombo (iGather, xGather, EMathOperator.Add);
            DefineVariable calcCommand = new DefineVariable (calculation);
            CmdDefineVariable executeCalculation = new CmdDefineVariable ("ii", calcCommand);

            mainCode.addChild (xDefineCommand);
            mainCode.addChild (iDefineCommand);
            mainCode.addChild (executeCalculation);
            mainCode.execute ();

            //ConcreteVariable iiGather = new ConcreteVariable ("ii");

            string expected = "105";
            string actual = mainCode.variables["ii"].Value;
            Assert.AreEqual (expected, actual);
        }
        /// Author: Max Hamulyak
        /// Date: 26-06-2015
        /// <summary>
        /// Parses for loop header, and finds start and ending value of the regex, in doing this it build a tuple that
        /// can be used in the creation of the forloop codeblock.
        /// </summary>
        /// <returns>The for loop header.</returns>
        /// <param name="headerDeclaration">Header declaration.</param>
        /// <param name="headerLineNumber">Header line number.</param>
        protected override Tuple<Solver, CmdDefineVariable, CmdDefineVariable> ParseForLoopHeader(List<Token> headerDeclaration, int headerLineNumber)
        {
            if (headerDeclaration.Count == 2 && headerDeclaration [0].Type == ETokenType.FOR && headerDeclaration [1].Type == ETokenType.EOL) {

                Token t = headerDeclaration.First ();
                List<String> result = new List<string> ();
                GroupCollection groups = forLoopRegex.Match (t.Value).Groups;
                if (groups.Count > 1) {
                    foreach (var item in forLoopRegex.GetGroupNames()) {
                        result.Add (string.Format ("Group: {0}, Value: {1}", item, groups [item].Value));
                    }
                    int startValue;
                    int endValue;
                    int.TryParse (groups ["startingLow"].Value, out startValue);
                    int.TryParse (groups ["endingHigh"].Value, out endValue);

                    string varName = groups ["loopIndex"].Value;
                    VariableSolver a = new ConcreteVariable (varName);
                    VariableSolver b = new ConcreteVariable (new Variable (1, EVariableType.Int));
                    VariableSolver c = new ConcreteVariable (new Variable (endValue, EVariableType.Int));
                    CmdDefineVariable defineLoopVar = new CmdDefineVariable (varName, new DefineVariable (new ConcreteVariable (new Variable (startValue, EVariableType.Int))));
                    CmdDefineVariable incrementVar = new CmdDefineVariable (varName, new DefineVariable (new VariableCombo (a, b, EMathOperator.Add)));
                    ValueSolver vs = new ValueSolver (a, c, EComparisonOperator.ValueLessThan);

                    return new Tuple<Solver, CmdDefineVariable, CmdDefineVariable> (vs, defineLoopVar, incrementVar);
                } else {
                    throw IncompleteDeclarationOfCondition (headerLineNumber, ETokenType.FOR, forLoopStatementIndicatorValue);
                }
            } else {

                            Token startOfForBlock = headerDeclaration.FirstOrDefault (forLoopStatementStartBlockIndicator);
                if (startOfForBlock == null) {
                    if (headerDeclaration.Exists (x => x.Type == ETokenType.CommentLine)) {
                        throw CommentInsideCondition (headerLineNumber, ETokenType.FOR, forLoopStatementIndicatorValue);
                    } else {
                        throw IncompleteDeclarationOfCondition (headerLineNumber, ETokenType.FOR, forLoopStatementIndicatorValue);
                    }
                } else {
                    int startOfBlockIndex = headerDeclaration.IndexOf (startOfForBlock);
                    //First token indicates this should be WHILE Loop, so it can be skipped
                    List<Token> tokensTillRange = headerDeclaration.GetRange (1, startOfBlockIndex - 1);
                    if (startOfBlockIndex + 2 < headerDeclaration.Count) {
                        List<Token> tokensAfterRange = headerDeclaration.GetRange (startOfBlockIndex + 1, headerDeclaration.Count - startOfBlockIndex - 1);
                        tokensAfterRange.RemoveAll (x => x.Type == ETokenType.WhiteSpace || x.Type == ETokenType.CommentLine || x.Type == ETokenType.EOL);
                        if (tokensAfterRange.Count > 0) {
                            Token errorToken = tokensAfterRange.First ();
                            if (errorToken.Type == ETokenType.VARIABLE || errorToken.Type == ETokenType.Literal || errorToken.Type == ETokenType.FUNCTIONCall) {
                                throw ValueIndicatorAfterCondition (headerLineNumber, ETokenType.FOR, errorToken.Type, errorToken.Value);
                            } else {
                                throw BlockIndicatorAfterCondition (headerLineNumber, ETokenType.FOR, errorToken.Type);
                            }
                        }
                    }
                    tokensTillRange.RemoveAll (x => x.Type == ETokenType.WhiteSpace);
                    if (tokensTillRange.Count > 0) {
                        Token variableToken = tokensTillRange.FirstOrDefault (x => x.Type == ETokenType.VARIABLE);
                        Token assignmentToken = tokensTillRange.FirstOrDefault (x => x.Type == ETokenType.AssignmentOperator);
                        if (assignmentToken == null) {
                            throw MissingAsignmentOperatorAfterDeclaration (headerLineNumber, ":=", variableToken.Value);
                        }
                        Token literalToken = tokensTillRange.FirstOrDefault (x => x.Type == ETokenType.Literal);
                        if (literalToken == null) {
                            throw EmptyAssignment (headerLineNumber, ":=", variableToken.Value);
                        }
                        tokensTillRange.Remove (literalToken);
                        Token keyWordTOToken = tokensTillRange.FirstOrDefault (x => x.Type == ETokenType.KeyWord && x.Value == "to");
                        if (keyWordTOToken == null) {
                            throw ExpectedKeyWordBetween (headerLineNumber, "to", literalToken.Value, "do");
                        }
                        Token literalToken2 = tokensTillRange.FirstOrDefault (x => x.Type == ETokenType.Literal);
                        if (literalToken2 == null) {
                            throw ExpectedAssignmentBetweenKeyword (headerLineNumber, "to", "do");
                        }
                        tokensTillRange.Remove (literalToken2);
                        tokensTillRange.Remove (assignmentToken);
                        tokensTillRange.Remove (variableToken);
                        tokensTillRange.Remove (keyWordTOToken);
                        tokensTillRange.Remove (startOfForBlock);

                        if (tokensTillRange.Count > 0) {
                            Token errorToken = tokensTillRange.First ();
                            if (errorToken.Type == ETokenType.VARIABLE || errorToken.Type == ETokenType.Literal || errorToken.Type == ETokenType.FUNCTIONCall) {
                                throw ValueIndicatorInsideCondition (headerLineNumber, ETokenType.FOR, errorToken.Type, errorToken.Value);
                            } else {
                                throw BlockIndicatorInsideCondition (headerLineNumber, ETokenType.FOR, errorToken.Type);
                            }
                        } else {

                            int startValue;
                            int endValue;
                            int.TryParse (literalToken.Value, out startValue);
                            int.TryParse (literalToken2.Value, out endValue);

                            string varName = variableToken.Value;
                            VariableSolver a = new ConcreteVariable (varName);
                            VariableSolver b = new ConcreteVariable (new Variable (1, EVariableType.Int));
                            VariableSolver c = new ConcreteVariable (new Variable (endValue, EVariableType.Int));
                            CmdDefineVariable defineLoopVar = new CmdDefineVariable (varName, new DefineVariable (new ConcreteVariable (new Variable (startValue, EVariableType.Int))));
                            CmdDefineVariable incrementVar = new CmdDefineVariable (varName, new DefineVariable (new VariableCombo (a, b, EMathOperator.Add)));
                            ValueSolver vs = new ValueSolver (a, c, EComparisonOperator.ValueLessThan);

                            return new Tuple<Solver, CmdDefineVariable, CmdDefineVariable> (vs, defineLoopVar, incrementVar);
                        }
                    } else {
                        throw EmptyCondition (headerLineNumber, ETokenType.FOR, ":");
                    }
                }

            }
        }