private ExpressionParserOutput ParseStringExpression(string expression)
        {
            var sc = new StringExpressionParser {
                Variables = Variables
            };

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

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

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

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

            return(sc.Output);
        }
        private ExpressionParserOutput ParseStringExpression(string expression)
        {
            var sc = new StringExpressionParser {
                Variables = Variables
            };

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

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

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

            return(sc.Output);
        }
        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++;
        }