private ExpressionParserOutput ParseNumericExpression(string expression)
        {
            var nc = new NumericExpressionParser {
                Variables = Variables
            };

            nc.Compile(expression, Output.StringCounter, Output.LoopCounter);

            Output.StringCounter = nc.Output.StringCounter;
            Output.LoopCounter   = nc.Output.LoopCounter;
            Output.InitCode      = Output.InitCode + nc.Output.InitCode;

            foreach (var f in nc.Output.Functions)
            {
                if (!Output.Functions.Contains(f))
                {
                    Output.Functions.Add(f);
                }
            }

            foreach (KeyValuePair <string, string> kvp in nc.Variables)
            {
                if (!Variables.ContainsKey(kvp.Key))
                {
                    Variables.Add(kvp.Key, kvp.Value);
                }
            }

            return(nc.Output);
        }
        private void Factor(TokenParser parser)
        {
            if (_token == null)
            {
                return;
            }

            if (_token.TokenName == TokenParser.Tokens.LPAREN)
            {
                SkipWhiteSpace(parser);
                _token = parser.GetToken();
                SkipWhiteSpace(parser);
                Expression(parser);
                if (_token == null)
                {
                    return;
                }
                SkipWhiteSpace(parser);
                _token = parser.GetToken();
                SkipWhiteSpace(parser);
            }
            else if (_token.TokenName == TokenParser.Tokens.LABEL || TokenParser.GetNumericFunctionsList().Contains(_token.TokenName))
            {
                string name    = _token.TokenValue.ToUpper().Trim();
                bool   isArray = false;
                _hasLabel = true;

                switch (_token.TokenName)
                {
                case TokenParser.Tokens.LEN:
                    name = "LEN";
                    break;

                case TokenParser.Tokens.ASC:
                    name = "ASC";
                    break;

                case TokenParser.Tokens.RND:
                    name = "RND";
                    break;

                case TokenParser.Tokens.INSTR:
                    name = "INSTR";
                    break;
                }

                SkipWhiteSpace(parser);
                if (parser.Peek() != null && parser.Peek().TokenPeek != null &&
                    (parser.Peek().TokenPeek.TokenName == TokenParser.Tokens.LPAREN) || TokenParser.GetNumericFunctionsList().Contains(_token.TokenName))
                {
                    if (Variables.ContainsKey("varArray" + name) && Variables["varArray" + name].StartsWith("varArray" + name + " rmb "))
                    {
                        isArray = true;
                        int    paren = 1;
                        string exp   = "";

                        while (_token != null && paren >= 1)
                        {
                            var peek = parser.Peek();

                            if (peek != null && peek.TokenPeek != null && peek.TokenPeek.TokenValue != null)
                            {
                                if (peek.TokenPeek.TokenName == TokenParser.Tokens.LPAREN)
                                {
                                    paren++;
                                }
                                if (peek.TokenPeek.TokenName == TokenParser.Tokens.RPAREN)
                                {
                                    paren--;
                                    if (paren == 1)
                                    {
                                        SkipWhiteSpace(parser);
                                        parser.GetToken();
                                        SkipWhiteSpace(parser);
                                        exp    = exp + ")";
                                        _token = parser.GetToken();
                                        SkipWhiteSpace(parser);
                                        break;
                                    }
                                }
                                exp    = exp + peek.TokenPeek.TokenValue;
                                _token = parser.GetToken();
                            }
                            else
                            {
                                break;
                            }
                        }
                        var nc2 = new NumericExpressionParser {
                            Variables = Variables
                        };
                        nc2.Compile("(" + exp + ")", Output.StringCounter, Output.LoopCounter);

                        Output.StringCounter = nc2.Output.StringCounter;
                        Output.LoopCounter   = nc2.Output.LoopCounter;
                        Output.InitCode      = Output.InitCode + nc2.Output.InitCode;

                        foreach (KeyValuePair <string, string> kvp in nc2.Variables)
                        {
                            if (!Variables.ContainsKey(kvp.Key))
                            {
                                Variables.Add(kvp.Key, kvp.Value);
                            }
                        }

                        Output.Output = Output.Output + nc2.Output.Output;
                        Output.Output = Output.Output + " tfr x,d" + Environment.NewLine;
                        Output.Output = Output.Output + " tfr b,a" + Environment.NewLine;
                        Output.Output = Output.Output + " ldx #varArray" + name + Environment.NewLine;
                        Output.Output = Output.Output + " call ArrayIndexNumeric" + Environment.NewLine;
                        Output.Output = Output.Output + " ldb ,x+" + Environment.NewLine;
                        Output.Output = Output.Output + " lda ,x" + Environment.NewLine;
                        Output.Output = Output.Output + " tfr d,x" + Environment.NewLine;
                    }
                }
                if (!isArray && !TokenParser.GetNumericFunctionsList().Contains(_token.TokenName))
                {
                    _token = parser.GetToken();
                }
                SkipWhiteSpace(parser);

                if (_token != null && (_token.TokenName == TokenParser.Tokens.LPAREN || TokenParser.GetNumericFunctionsList().Contains(_token.TokenName)))
                {
                    if (_token.TokenName == TokenParser.Tokens.INSTR)
                    {
                        DoInstr(parser);

                        SkipWhiteSpace(parser);
                        _token = parser.GetToken();
                        return;
                    }
                    int    paren = 1;
                    string exp   = "";

                    while (_token != null && paren > 0)
                    {
                        var peek = parser.Peek();
                        if (peek != null && peek.TokenPeek != null && peek.TokenPeek.TokenValue != null)
                        {
                            if (peek.TokenPeek.TokenName == TokenParser.Tokens.LPAREN)
                            {
                                paren++;
                            }
                            if (peek.TokenPeek.TokenName == TokenParser.Tokens.RPAREN)
                            {
                                paren--;
                                if (paren == 0)
                                {
                                    _token = parser.GetToken();
                                    break;
                                }
                            }
                            exp    = exp + peek.TokenPeek.TokenValue;
                            _token = parser.GetToken();
                        }
                        else
                        {
                            break;
                        }
                    }
                    IExpressionParser eParser = BooleanExpressionParser.IsString(exp)
                        ? (IExpressionParser) new StringExpressionParser()
                        : new NumericExpressionParser();

                    eParser.Variables = Variables;
                    eParser.Compile(exp, Output.StringCounter, Output.LoopCounter);

                    Output.StringCounter = eParser.Output.StringCounter;
                    Output.LoopCounter   = eParser.Output.LoopCounter;
                    Output.InitCode      = Output.InitCode + eParser.Output.InitCode;

                    foreach (KeyValuePair <string, string> kvp in eParser.Variables)
                    {
                        if (!Variables.ContainsKey(kvp.Key))
                        {
                            Variables.Add(kvp.Key, kvp.Value);
                        }
                    }

                    //Output.Output = Output.Output + " push y" + Environment.NewLine;
                    //if (BooleanExpressionParser.IsString(exp))
                    //    Output.Output = Output.Output + " ldy #TheBasicStrBuf" + Environment.NewLine;
                    //Output.Output = Output.Output + eParser.Output.Output;
                    //if (BooleanExpressionParser.IsString(exp))
                    //    Output.Output = Output.Output + " ldx #TheBasicStrBuf" + Environment.NewLine;
                    //if (name.Trim().ToUpper() == "INPUT")
                    //    Output.Output = Output.Output + " call func" + name + "2" + Environment.NewLine;
                    //else Output.Output = Output.Output + " call func" + name + Environment.NewLine;
                    //Output.Output = Output.Output + " pop y" + Environment.NewLine;

                    Output.Output = Output.Output + eParser.Output.Output;
                    if (BooleanExpressionParser.IsString(exp))
                    {
                        Output.Output = Output.Output + " push y" + Environment.NewLine;
                        Output.Output = Output.Output + " push x" + Environment.NewLine;
                        Output.Output = Output.Output + " call func" + name + Environment.NewLine;
                        Output.Output = Output.Output + " tfr x,y" + Environment.NewLine;
                        Output.Output = Output.Output + " pop x" + Environment.NewLine;
                        Output.Output = Output.Output + " call freememory" + Environment.NewLine;
                        Output.Output = Output.Output + " tfr y,x" + Environment.NewLine;
                        Output.Output = Output.Output + " pop y" + Environment.NewLine;
                    }
                    else
                    {
                        Output.Output = Output.Output + " call func" + name + Environment.NewLine;
                    }

                    SkipWhiteSpace(parser);
                    _token = parser.GetToken();
                    SkipWhiteSpace(parser);
                }
                else
                {
                    if (!isArray)
                    {
                        Output.Output = Output.Output + " ldx var" + name + Environment.NewLine;
                    }
                    AddVariable("var" + name);
                }
            }
            else
            {
                if (_token.TokenName == TokenParser.Tokens.HEXNUMBER)
                {
                    Output.Output = Output.Output + " ldx #$" + _token.TokenValue.Replace("&h", "").Replace("&H", "") + Environment.NewLine;
                }
                else
                {
                    Output.Output = Output.Output + " ldx #" + _token.TokenValue + Environment.NewLine;
                }
                SkipWhiteSpace(parser);
                _token = parser.GetToken();
                SkipWhiteSpace(parser);
            }
        }
        private void DoInstr(TokenParser parser)
        {
            SkipWhiteSpace(parser);

            string exp1 = GetNumericExpression(parser, false);

            SkipWhiteSpace(parser);
            // Should be a comma
            parser.GetToken();
            SkipWhiteSpace(parser);

            string exp2 = GetStringExpression(parser);

            SkipWhiteSpace(parser);
            // Should be a comma
            parser.GetToken();
            SkipWhiteSpace(parser);

            string exp3 = GetStringExpression(parser).Trim();

            //exp3 = exp3.Remove(exp3.Length - 1, 1);

            SkipWhiteSpace(parser);
            // Should be closing parenthesis
            parser.GetToken();
            SkipWhiteSpace(parser);

            StringExpressionParser sourceString = new StringExpressionParser {
                Variables = Variables
            };

            sourceString.Compile(exp2, Output.StringCounter, Output.LoopCounter);

            Output.StringCounter = sourceString.Output.StringCounter;
            Output.LoopCounter   = sourceString.Output.LoopCounter;
            Output.BoolCounter   = sourceString.Output.BoolCounter;
            Output.InitCode      = Output.InitCode + sourceString.Output.InitCode;

            foreach (Functions f in sourceString.Output.Functions)
            {
                if (!Output.Functions.Contains(f))
                {
                    Output.Functions.Add(f);
                }
            }

            string param2Code = sourceString.Output.Output;

            StringExpressionParser destString = new StringExpressionParser {
                Variables = Variables
            };

            destString.Compile(exp3, Output.StringCounter, Output.LoopCounter);

            Output.StringCounter = destString.Output.StringCounter;
            Output.LoopCounter   = destString.Output.LoopCounter;
            Output.BoolCounter   = destString.Output.BoolCounter;
            Output.InitCode      = Output.InitCode + destString.Output.InitCode;

            foreach (Functions f in destString.Output.Functions)
            {
                if (!Output.Functions.Contains(f))
                {
                    Output.Functions.Add(f);
                }
            }

            string param3Code = destString.Output.Output;

            NumericExpressionParser startIndex = new NumericExpressionParser {
                Variables = Variables
            };

            startIndex.Compile(exp1, Output.StringCounter, Output.LoopCounter);

            Output.StringCounter = startIndex.Output.StringCounter;
            Output.LoopCounter   = startIndex.Output.LoopCounter;
            Output.BoolCounter   = startIndex.Output.BoolCounter;
            Output.InitCode      = Output.InitCode + startIndex.Output.InitCode;

            Output.Output = Output.Output + startIndex.Output.Output;
            Output.Output = Output.Output + " push x" + Environment.NewLine;
            Output.Output = Output.Output + param2Code;
            Output.Output = Output.Output + " push x" + Environment.NewLine;
            Output.Output = Output.Output + param3Code;
            Output.Output = Output.Output + " call funcINSTR" + Environment.NewLine;
        }
        public void Compile(string expression, int stringCounter, int loopCounter, int boolCounter)
        {
            ExpressionParserOutput output = new ExpressionParserOutput
            {
                StringCounter = stringCounter,
                LoopCounter   = loopCounter,
                BoolCounter   = boolCounter
            };

            var chains = new List <BoolExpressionChain>();
            int id     = 1;

            Output = output;
            TokenParser parser = new TokenParser {
                InputString = expression
            };

            TokenParser.Tokens connOp;

            do
            {
                string leftExpression  = "";
                string rightExpression = "";
                Token  token;
                while (parser.Peek() != null && parser.Peek().TokenPeek != null &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.LESSTHAN &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.LESSTHANOREQUAL &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.GREATERTHAN &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.GREATERTHENOREQUAL &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.NOTEQUAL &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.EQUAL)
                {
                    token          = parser.GetToken();
                    leftExpression = leftExpression + token.TokenValue;
                }
                leftExpression = leftExpression.Trim();

                token = parser.GetToken();
                var equalityToken = token.TokenName;

                while (parser.Peek() != null && parser.Peek().TokenPeek != null &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.OR &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.AND &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.LESSTHAN &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.LESSTHANOREQUAL &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.GREATERTHAN &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.GREATERTHENOREQUAL &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.NOTEQUAL &&
                       parser.Peek().TokenPeek.TokenName != TokenParser.Tokens.EQUAL)
                {
                    token           = parser.GetToken();
                    rightExpression = rightExpression + token.TokenValue;
                }
                rightExpression = rightExpression.Trim();

                IExpressionParser eParser;
                string            pre = "";
                if (!IsString(leftExpression, rightExpression))
                {
                    eParser = new NumericExpressionParser();
                }
                else
                {
                    eParser = new StringExpressionParser();
                }

                eParser.Variables = Variables;
                eParser.Compile(leftExpression, Output.StringCounter, Output.LoopCounter);

                Output.StringCounter = eParser.Output.StringCounter;
                Output.LoopCounter   = eParser.Output.LoopCounter;

                Output.InitCode = Output.InitCode + eParser.Output.InitCode;

                foreach (var f in eParser.Output.Functions)
                {
                    AddFunction(f);
                }

                foreach (KeyValuePair <string, string> kvp in eParser.Variables)
                {
                    if (!Variables.ContainsKey(kvp.Key))
                    {
                        Variables.Add(kvp.Key, kvp.Value);
                    }
                }

                string leftOutput = pre + eParser.Output.Output;

                pre = "";

                if (!IsString(leftExpression, rightExpression))
                {
                    eParser = new NumericExpressionParser();
                }
                else
                {
                    eParser = new StringExpressionParser();
                }

                eParser.Variables = Variables;
                eParser.Compile(rightExpression, Output.StringCounter, Output.LoopCounter);

                Output.StringCounter = eParser.Output.StringCounter;
                Output.LoopCounter   = eParser.Output.LoopCounter;

                Output.InitCode = Output.InitCode + eParser.Output.InitCode;

                foreach (var f in eParser.Output.Functions)
                {
                    AddFunction(f);
                }

                foreach (KeyValuePair <string, string> kvp in eParser.Variables)
                {
                    if (!Variables.ContainsKey(kvp.Key))
                    {
                        Variables.Add(kvp.Key, kvp.Value);
                    }
                }

                string rightOutput = pre + eParser.Output.Output;

                SkipWhiteSpace(parser);

                connOp = TokenParser.Tokens.UNDEFINED;

                if (parser.Peek() != null && parser.Peek().TokenPeek != null &&
                    parser.Peek().TokenPeek.TokenName == TokenParser.Tokens.AND)
                {
                    connOp = TokenParser.Tokens.AND;
                }
                if (parser.Peek() != null && parser.Peek().TokenPeek != null &&
                    parser.Peek().TokenPeek.TokenName == TokenParser.Tokens.OR)
                {
                    connOp = TokenParser.Tokens.OR;
                }

                chains.Add(new BoolExpressionChain
                {
                    Id = id,
                    ConnectionOperator = connOp,
                    Expression         = new BoolExpression
                    {
                        EquityOperator      = equalityToken,
                        LeftSideCode        = leftOutput,
                        RightSideCode       = rightOutput,
                        LeftSideExpression  = leftExpression,
                        RightSideExpression = rightExpression,
                        IsString            = IsString(leftExpression, rightExpression)
                    }
                });
                id++;

                if (connOp != TokenParser.Tokens.UNDEFINED)
                {
                    parser.GetToken();
                }
            } while (connOp != TokenParser.Tokens.UNDEFINED);

            //if (!leftExpression.Contains('$') && !rightExpression.Contains('$'))
            //{
            //    Output.Output = DoCompare(leftOutput, rightOutput, equalityToken);
            //}
            string output2 = "";

            foreach (BoolExpressionChain chain in chains.OrderBy(z => z.Id))
            {
                if (chain.ConnectionOperator == TokenParser.Tokens.AND || chain.ConnectionOperator == TokenParser.Tokens.UNDEFINED)
                {
                    output2 = output2 + DoCompare(chain.Expression);
                    output2 = output2 + " cmpx #0" + Environment.NewLine;
                    output2 = output2 + " jeq boolexit" + Output.BoolCounter + Environment.NewLine;
                }
                else if (chain.ConnectionOperator == TokenParser.Tokens.OR)
                {
                    output2 = output2 + DoCompare(chain.Expression);
                    output2 = output2 + " cmpx #1" + Environment.NewLine;
                    output2 = output2 + " jeq boolexitor" + Output.BoolCounter + Environment.NewLine;
                }
            }
            output2 = output2 + "boolexitor" + Output.BoolCounter + " ldx #1" + Environment.NewLine;
            output2 = output2 + " jmp booltrue" + Output.BoolCounter + Environment.NewLine;
            output2 = output2 + "boolexit" + output.BoolCounter + " ldx #0" + Environment.NewLine;
            output2 = output2 + "booltrue" + output.BoolCounter + " nop" + Environment.NewLine;

            Output.Output = output2;
            Output.BoolCounter++;
        }
        public void Compile(string expression, int stringCounter, int loopCounter)
        {
            var parser = new TokenParser();

            ExpressionParserOutput output = new ExpressionParserOutput
            {
                StringCounter = stringCounter,
                LoopCounter   = loopCounter
            };

            Output = output;

            parser.InputString = expression;

            SkipWhiteSpace(parser);
            Token token = parser.GetToken();

            while (token != null && token.TokenName != TokenParser.Tokens.NEWLINE)
            {
                SkipWhiteSpace(parser);
                if (token.TokenName == TokenParser.Tokens.STRING)
                {
                    if (token.TokenValue == "\"\"")
                    {
                        Output.InitCode = Output.InitCode + "st" + Output.StringCounter + " chr 0" + Environment.NewLine;
                    }
                    else
                    {
                        Output.InitCode = Output.InitCode + "st" + Output.StringCounter + " str " + token.TokenValue +
                                          Environment.NewLine;
                        Output.InitCode = Output.InitCode + " chr 0" + Environment.NewLine;
                    }

                    Output.Output = Output.Output + " ldx #st" + Output.StringCounter + Environment.NewLine;
                    Output.Output = Output.Output + "loop" + Output.LoopCounter + " lda ,x+" + Environment.NewLine;
                    Output.Output = Output.Output + " cmpa #0" + Environment.NewLine;
                    Output.Output = Output.Output + " jeq exitLoop" + Output.LoopCounter + Environment.NewLine;
                    Output.Output = Output.Output + " sta ,y+" + Environment.NewLine;
                    Output.Output = Output.Output + " jmp loop" + Output.LoopCounter + Environment.NewLine;
                    Output.Output = Output.Output + "exitLoop" + Output.LoopCounter + " sta ,y" + Environment.NewLine;
                    Output.LoopCounter++;
                    Output.StringCounter++;
                }
                if (token.TokenName == TokenParser.Tokens.PLUS)
                {
                    //token = parser.GetToken();
                    //continue;
                }
                if (token.TokenName == TokenParser.Tokens.STRINGLABEL)
                {
                    string varName = token.TokenValue.Replace("$", "").ToUpper();
                    SkipWhiteSpace(parser);

                    if (parser.Peek() != null && parser.Peek().TokenPeek != null &&
                        parser.Peek().TokenPeek.TokenName == TokenParser.Tokens.LPAREN)
                    {
                        parser.GetToken();
                        SkipWhiteSpace(parser);
                        string exp = GetNumericExpression(parser);

                        var nc = new NumericExpressionParser {
                            Variables = Variables
                        };
                        nc.Compile(exp, Output.StringCounter, Output.LoopCounter);

                        Output.StringCounter = nc.Output.StringCounter;
                        Output.LoopCounter   = nc.Output.LoopCounter;

                        foreach (var f in nc.Output.Functions)
                        {
                            AddFunction(f);
                        }
                        string ndxCode = nc.Output.Output;

                        Output.Output = Output.Output + ndxCode;
                        Output.Output = Output.Output + " tfr x,d" + Environment.NewLine;
                        Output.Output = Output.Output + " tfr b,a" + Environment.NewLine;
                        Output.Output = Output.Output + " ldx #varStrArray" + varName + Environment.NewLine;
                        Output.Output = Output.Output + " call ArrayIndexString" + Environment.NewLine;
                        Output.Output = Output.Output + "loop" + Output.LoopCounter + " lda ,x+" + Environment.NewLine;
                        Output.Output = Output.Output + " cmpa #0" + Environment.NewLine;
                        Output.Output = Output.Output + " jeq exitLoop" + Output.LoopCounter + Environment.NewLine;
                        Output.Output = Output.Output + " sta ,y+" + Environment.NewLine;
                        Output.Output = Output.Output + " jmp loop" + Output.LoopCounter + Environment.NewLine;
                        Output.Output = Output.Output + "exitLoop" + Output.LoopCounter + " sta ,y" +
                                        Environment.NewLine;
                        Output.LoopCounter++;
                    }
                    else
                    {
                        Output.Output = Output.Output + " ldx #varStr" + varName + Environment.NewLine;
                        Output.Output = Output.Output + "loop" + Output.LoopCounter + " lda ,x+" + Environment.NewLine;
                        Output.Output = Output.Output + " cmpa #0" + Environment.NewLine;
                        Output.Output = Output.Output + " jeq exitLoop" + Output.LoopCounter + Environment.NewLine;
                        Output.Output = Output.Output + " sta ,y+" + Environment.NewLine;
                        Output.Output = Output.Output + " jmp loop" + Output.LoopCounter + Environment.NewLine;
                        Output.Output = Output.Output + "exitLoop" + Output.LoopCounter + " sta ,y" +
                                        Environment.NewLine;
                        Output.LoopCounter++;
                    }
                }

                if (token.TokenName == TokenParser.Tokens.UCASE)
                {
                    string exp = GetStringExpression(parser);

                    ExpressionParserOutput o = ParseStringExpression(exp);

                    AddFunction(Functions.FuncUcase);

                    Output.Output = Output.Output + " push y" + Environment.NewLine;
                    Output.Output = Output.Output + o.Output;
                    Output.Output = Output.Output + " pop y" + Environment.NewLine;
                    Output.Output = Output.Output + " call funcUCASE" + Environment.NewLine;
                }
                if (token.TokenName == TokenParser.Tokens.LCASE)
                {
                    string exp = GetStringExpression(parser);

                    ExpressionParserOutput o = ParseStringExpression(exp);

                    AddFunction(Functions.FuncLcase);

                    Output.Output = Output.Output + " push y" + Environment.NewLine;
                    Output.Output = Output.Output + o.Output;
                    Output.Output = Output.Output + " pop y" + Environment.NewLine;
                    Output.Output = Output.Output + " call funcLCASE" + Environment.NewLine;
                }
                if (token.TokenName == TokenParser.Tokens.INPUT)
                {
                    SkipWhiteSpace(parser);
                    // Should be a left parenthesis
                    parser.GetToken();
                    // Should be a right parenthesis
                    parser.GetToken();

                    Output.Output = Output.Output + " call funcINPUT" + Environment.NewLine;

                    Output.Output = Output.Output + " ldx #InputBuffer" + Environment.NewLine;
                    Output.Output = Output.Output + "loop" + Output.LoopCounter + " lda ,x+" + Environment.NewLine;
                    Output.Output = Output.Output + " cmpa #0" + Environment.NewLine;
                    Output.Output = Output.Output + " jeq exitLoop" + Output.LoopCounter + Environment.NewLine;
                    Output.Output = Output.Output + " sta ,y+" + Environment.NewLine;
                    Output.Output = Output.Output + " jmp loop" + Output.LoopCounter + Environment.NewLine;
                    Output.Output = Output.Output + "exitLoop" + Output.LoopCounter + " sta ,y" + Environment.NewLine;
                    Output.LoopCounter++;

                    AddFunction(Functions.FuncInput);
                    AddFunction(Functions.FuncPrint);
                }
                if (token.TokenName == TokenParser.Tokens.CHR)
                {
                    SkipWhiteSpace(parser);
                    // Should be a left parenthesis
                    parser.GetToken();
                    string exp = GetNumericExpression(parser);
                    ExpressionParserOutput o = ParseNumericExpression(exp);
                    SkipWhiteSpace(parser);

                    // Should be a right parenthesis
                    parser.GetToken();
                    SkipWhiteSpace(parser);

                    Output.Output = Output.Output + o.Output;
                    Output.Output = Output.Output + " tfr x,d" + Environment.NewLine;
                    Output.Output = Output.Output + " stb ,y+" + Environment.NewLine;
                    Output.Output = Output.Output + " sta ,y" + Environment.NewLine;
                }
                if (token.TokenName == TokenParser.Tokens.MID)
                {
                    string exp = GetStringExpression(parser);

                    ExpressionParserOutput o = ParseStringExpression(exp);
                    SkipWhiteSpace(parser);

                    // Should be a comma
                    parser.GetToken();
                    SkipWhiteSpace(parser);

                    Output.Output = Output.Output + " push y" + Environment.NewLine;
                    Output.Output = Output.Output + o.Output;
                    Output.Output = Output.Output + " pop y" + Environment.NewLine;

                    exp = GetNumericExpression(parser);
                    o   = ParseNumericExpression(exp);
                    SkipWhiteSpace(parser);

                    // Should be a comma
                    parser.GetToken();
                    SkipWhiteSpace(parser);

                    Output.Output = Output.Output + "" + Environment.NewLine;
                    Output.Output = Output.Output + o.Output;
                    Output.Output = Output.Output + " tfr x,d" + Environment.NewLine;
                    Output.Output = Output.Output + " push d" + Environment.NewLine;

                    exp = GetNumericExpression(parser);
                    o   = ParseNumericExpression(exp);
                    SkipWhiteSpace(parser);

                    Output.Output = Output.Output + o.Output;
                    Output.Output = Output.Output + " pop d" + Environment.NewLine;

                    Output.Output = Output.Output + " call funcMID" + Environment.NewLine;

                    AddFunction(Functions.FuncMid);
                }
                token = parser.GetToken();
            }
        }