public override Expression Resolve()
        {
            for (int i = 0; i < this.Expressions.Length; ++i)
            {
                this.Expressions[i] = this.Expressions[i].Resolve();
            }

            for (int i = 1; i < this.Expressions.Length - 1; ++i)
            {
                if (!this.IsSimpleEnough(this.Expressions[i]))
                {
                    throw new ParserException(this.Expressions[i].FirstToken,
                        "Complex expressions are not allowed as the inner elements of comparison chains. " +
                        "This is because this expression must be expanded from e.g. a < b < c to a < b && b < c, " +
                        "thus causing inner elements to be invoked multiple times.");
                }
            }

            List<Expression> output = new List<Expression>();

            for (int i = 0; i < this.Expressions.Length - 1; ++i)
            {
                Expression left = this.Expressions[i];
                Expression right = this.Expressions[i + 1];
                Expression single = new BinaryOpChain(new Expression[] { left, right }, new Token[] { this.OpTokens[i] });
                output.Add(single);
            }

            if (output.Count == 1) return output[0];
            List<Token> andTokens = new List<Token>();
            while (andTokens.Count < output.Count - 1)
            {
                andTokens.Add(new Token("and", null, 0, 0, TokenType.ALPHANUM));
            }
            return new BinaryOpChain(output, andTokens);
        }
 private void SerializeBinaryOpChain(List<string> output, BinaryOpChain opChain)
 {
     for (int i = 0; i < opChain.Expressions.Length; ++i)
     {
         if (i > 0)
         {
             output.Add(" ");
             output.Add(opChain.OpTokens[i - 1].Value);
             output.Add(" ");
         }
         SerializeExpression(output, opChain.Expressions[i]);
     }
 }
        private ForLoop ResolveWithRange(Expression[] rangeArgs)
        {
            List<Executable> init = new List<Executable>();

            Expression increment = new IntegerConstant(null, 1);
            if (rangeArgs.Length == 3)
            {
                if (rangeArgs[2] is IntegerConstant || rangeArgs[2] is Variable)
                {
                    increment = rangeArgs[2];
                }
                string variableName = "crayon_conversion_step_" + VARIABLE_ALLOCATION_COUNTER++;
                init.Add(new Assignment(new Variable(null, variableName), new Token("=", null, 0, 0, TokenType.OTHER), rangeArgs[2]));
                increment = new Variable(null, variableName);
            }

            Expression start = new IntegerConstant(null, 0);
            // if 2 or 3 are present, then an explicit start is given
            if (rangeArgs.Length > 1)
            {
                start = rangeArgs[0];
            }

            Expression end = null;
            if (rangeArgs.Length == 1)
            {
                end = rangeArgs[0];
            }
            else
            {
                end = rangeArgs[1];
            }

            if (end is IntegerConstant || end is Variable)
            {
                // this is fine
            }
            else
            {
                string variableName = "crayon_conversion_length_" + VARIABLE_ALLOCATION_COUNTER++;
                init.Add(new Assignment(new Variable(null, variableName), new Token("=", null, 0, 0, TokenType.OTHER), end));
                end = new Variable(null, variableName);
            }

            init.Add(new Assignment(new Variable(this.IteratorVariable, this.IteratorVariable.Value), new Token("=", null, 0, 0, TokenType.OTHER), start));
            Expression condition = new BinaryOpChain(
                new Expression[] {
                    new Variable(this.IteratorVariable, this.IteratorVariable.Value),
                    end },
                new Token[] { new Token("<", null, 0, 0, TokenType.OTHER) });

            List<Executable> step = new List<Executable>()
            {
                new Assignment(
                    new Variable(this.IteratorVariable, this.IteratorVariable.Value),
                    new Token("+=", null, 0, 0, TokenType.OTHER),
                    increment)
            };

            return new ForLoop(this.FirstToken, this, init, condition, step, this.Body);
        }