private Expression CompileBinaryExpression(int baseLevel, int lambdaLevel) { Expression current = CompileUnaryExpression(lambdaLevel); PushPosition(); while (!End) { BinaryOperator op = ExpressionSnippets.GetBinaryOperator(GetPunctuation()); if (op == BinaryOperator.None) { break; } if (ExpressionSnippets.GetOperatorLevel(op) <= baseLevel) { break; } else { Move(); int fromPos = PeekPos(); int toPos = Pos; current = new BinaryExpression(op, current, CompileBinaryExpression(ExpressionSnippets.GetOperatorLevel(op), lambdaLevel), fromPos, toPos); } } PopPosition(); return(current); }
public override Expression Reduce(Expression root, ExpressionReductor reductor) { if (root is BinaryExpression) { Expression left = reductor.Reduce((root as BinaryExpression).Left); Expression right = reductor.Reduce((root as BinaryExpression).Right); if (left is BinaryExpression && ExpressionSnippets.GetOperatorLevel((left as BinaryExpression).Operator) == ExpressionSnippets.GetOperatorLevel((root as BinaryExpression).Operator)) { Expression ll = reductor.Reduce((left as BinaryExpression).Left); Expression lr = reductor.Reduce((left as BinaryExpression).Right); if (lr.IsConstantExpression()) { return(BinaryExpression.Create((left as BinaryExpression).Operator, ll, BinaryExpression.Create((root as BinaryExpression).Operator, lr, right))); } } } return(root); }
private void CheckUnaryExpression(UnaryExpression e, TypeCheckingContext context) { PerformTypeChecking(e.Operand, context); Type type = null; bool isValid = true; if (e.Operator == UnaryOperator.Negation) { if (Types.IsNumberType(e.Operand.Type)) { type = e.Operand.Type; } else { isValid = false; } } else if (e.Operator == UnaryOperator.Not) { if (Types.GetPrimitiveTypeIndex(e.Operand.Type) == 7) { type = typeof(bool); } else { isValid = false; } } else if (e.Operator == UnaryOperator.Identity) { if (Types.IsNumberType(e.Operand.Type)) { type = e.Operand.Type; } else { isValid = false; } } if (isValid) { e.Type = type; } else { context.ErrorProvider.ThrowException(string.Format("Operator {0} cannot be applied to type {1}.", ExpressionSnippets.SerializeUnaryOperator(e.Operator), e.Operand.Type), e); } }
protected virtual void CheckBinaryExpresionType(BinaryExpression e, TypeCheckingContext context) { Type type = null; bool isValid = true; if (e.Left.Type == null && e.Right.Type == null) { isValid = false; } else if (e.Operator == BinaryOperator.Assign) { if (!(e.Left is VariableExpression || e.Left is IndexingExpression)) { context.ErrorProvider.ThrowException("Can only assign to a variable.", e); return; } } else if (e.Operator == BinaryOperator.Add) { if (e.Left.Type == typeof(char) || e.Right.Type == typeof(char)) { type = typeof(string); } else if (e.Left.Type == typeof(string) || e.Right.Type == typeof(string)) { type = typeof(string); } else if (Types.IsNumberType(e.Left.Type) && Types.IsNumberType(e.Right.Type)) { int index = Types.ResolvePrimitiveTypeIndex(e.Left.Type, e.Right.Type); type = Types.GetPrimitiveType(index); } else { isValid = false; } } else if (e.Operator == BinaryOperator.Subtract || e.Operator == BinaryOperator.Multiply || e.Operator == BinaryOperator.Divide) { if (Types.IsNumberType(e.Left.Type) && Types.IsNumberType(e.Right.Type)) { int index = Types.ResolvePrimitiveTypeIndex(e.Left.Type, e.Right.Type); type = Types.GetPrimitiveType(index); } else if (e.Left.Type.Name == "Matrix" && e.Right.Type.Name == "Matrix") { type = e.Left.Type; } else { isValid = false; } } else if (e.Operator == BinaryOperator.LessThan || e.Operator == BinaryOperator.LessEqualThan || e.Operator == BinaryOperator.GreaterThan || e.Operator == BinaryOperator.GreaterEqualThan) { if (e.Left.Type == typeof(string) && e.Right.Type == typeof(string)) { type = typeof(bool); } else if (Types.IsNumberType(e.Left.Type) && Types.IsNumberType(e.Right.Type)) { type = typeof(bool); } else { isValid = false; } } else if (e.Operator == BinaryOperator.Equal || e.Operator == BinaryOperator.NotEqual) { if (e.Left.Type == typeof(string) && e.Right.Type == typeof(string)) { type = typeof(bool); } else if (Types.IsNumberType(e.Left.Type) && Types.IsNumberType(e.Right.Type)) { type = typeof(bool); } else if (Types.GetPrimitiveTypeIndex(e.Left.Type) == 7 && Types.GetPrimitiveTypeIndex(e.Right.Type) == 7) { type = typeof(bool); } else if (e.Left is ConstantExpression && ((ConstantExpression)e.Left).Value == null && !Types.IsPrimitiveType(e.Right.Type)) { type = typeof(bool); } else if (e.Right is ConstantExpression && ((ConstantExpression)e.Right).Value == null && !Types.IsPrimitiveType(e.Left.Type)) { type = typeof(bool); } else { isValid = false; } } else if (e.Operator == BinaryOperator.And || e.Operator == BinaryOperator.Or) { if (e.Left.Type == typeof(bool) || e.Right.Type == typeof(bool)) { type = typeof(bool); } else { isValid = false; } } if (isValid) { e.Type = type; } else if (context != null) { context.ErrorProvider.ThrowException(string.Format("Operator {0} cannot be applied to types of {1} and {2}.", ExpressionSnippets.SerializeBinaryOperator(e.Operator), e.Left.Type, e.Right.Type), e); } }