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 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); }
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]); } }