/// <summary> /// Create a <see cref="LSLBinaryExpressionNode" /> from two <see cref="ILSLExprNode" />'s and an operator description. /// </summary> /// <param name="resultType"> /// The resulting type of the binary operation between <paramref name="leftExpression" /> and /// <paramref name="rightExpression" />. /// </param> /// <param name="leftExpression">The left expression.</param> /// <param name="operation">The operator.</param> /// <param name="rightExpression">The right expression.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="leftExpression" /> or <paramref name="rightExpression" /> is /// <c>null</c>. /// </exception> /// <exception cref="ArgumentException"> /// Thrown if <paramref name="resultType" /> is equal to <see cref="LSLType.Void" /> or /// <paramref name="operation" /> is equal to <see cref="LSLBinaryOperationType.Error" /> /// </exception> public LSLBinaryExpressionNode(LSLType resultType, ILSLExprNode leftExpression, LSLBinaryOperationType operation, ILSLExprNode rightExpression) { if (leftExpression == null) { throw new ArgumentNullException("leftExpression"); } if (rightExpression == null) { throw new ArgumentNullException("rightExpression"); } if (resultType == LSLType.Void) { throw new ArgumentException("Binary operation resultType cannot be LSLType.Void.", "resultType"); } Type = resultType; LeftExpression = leftExpression; LeftExpression.Parent = this; Operation = operation; OperationString = operation.ToOperatorString(); RightExpression = rightExpression; RightExpression.Parent = this; }
/// <summary> /// Determines if the <see cref="LSLBinaryOperationType" /> is a form of modifying assignment that is not just a plain /// assign operation. /// </summary> /// <param name="type">The <see cref="LSLBinaryOperationType" /> to test.</param> /// <returns> /// True if the provided <see cref="LSLBinaryOperationType" /> is a ModifyAssignOperation such as (+=). False if /// it is a plain assignment operator, or other type of operator. /// </returns> public static bool IsModifyAssign(this LSLBinaryOperationType type) { return(type == LSLBinaryOperationType.AddAssign || type == LSLBinaryOperationType.DivideAssign || type == LSLBinaryOperationType.ModulusAssign || type == LSLBinaryOperationType.MultiplyAssign || type == LSLBinaryOperationType.SubtractAssign); }
/// <summary> /// Construct an <see cref="LSLBinaryOperationSignature" /> from an <see cref="LSLBinaryOperationType" />, the /// operations return type, /// the return type of the expression on the left and the return type of the expression on the right. /// </summary> /// <param name="operation">The <see cref="LSLBinaryOperationType" /> of the binary operation signature.</param> /// <param name="returns">The return type of the binary operation.</param> /// <param name="left">The return type of the expression on the left side of the binary operation.</param> /// <param name="right">The return type of the expression on the right side of the binary operation.</param> public LSLBinaryOperationSignature(LSLBinaryOperationType operation, LSLType returns, LSLType left, LSLType right) { Returns = returns; Left = left; Right = right; Operation = operation; }
/// <summary> /// Converts an <see cref="LSLBinaryOperationType" /> into is source code equivalent string. /// </summary> /// <param name="type">The <see cref="LSLBinaryOperationType" /> to convert to a string.</param> /// <returns>The source code equivalent string representation of the provided <see cref="LSLBinaryOperationType" />.</returns> /// <exception cref="ArgumentException"> /// Thrown if the <see cref="LSLBinaryOperationType" /> provided is equal to /// <see cref="LSLBinaryOperationType.Error" /> /// </exception> public static string ToOperatorString(this LSLBinaryOperationType type) { switch (type) { case LSLBinaryOperationType.Assign: return("="); case LSLBinaryOperationType.Add: return("+"); case LSLBinaryOperationType.Subtract: return("-"); case LSLBinaryOperationType.Divide: return("/"); case LSLBinaryOperationType.Modulus: return("%"); case LSLBinaryOperationType.Multiply: return("*"); case LSLBinaryOperationType.BitwiseXor: return("^"); case LSLBinaryOperationType.BitwiseOr: return("|"); case LSLBinaryOperationType.BitwiseAnd: return("&"); case LSLBinaryOperationType.LessThan: return("<"); case LSLBinaryOperationType.GreaterThan: return(">"); case LSLBinaryOperationType.Equals: return("=="); case LSLBinaryOperationType.NotEquals: return("!="); case LSLBinaryOperationType.AddAssign: return("+="); case LSLBinaryOperationType.SubtractAssign: return("-="); case LSLBinaryOperationType.DivideAssign: return("/="); case LSLBinaryOperationType.ModulusAssign: return("%="); case LSLBinaryOperationType.MultiplyAssign: return("*="); case LSLBinaryOperationType.LogicalOr: return("||"); case LSLBinaryOperationType.LogicalAnd: return("&&"); case LSLBinaryOperationType.LessThanEqual: return("<="); case LSLBinaryOperationType.GreaterThanEqual: return(">="); case LSLBinaryOperationType.LeftShift: return("<<"); case LSLBinaryOperationType.RightShift: return(">>"); } throw new ArgumentException( string.Format("Could not convert LSLBinaryOperationType.{0} enum value to operator string", type), "type"); }
/// <summary> /// Determines if the <see cref="LSLBinaryOperationType" /> is a direct assignment, or a modifying assignment /// operation. /// Effectively: (type == <see cref="LSLBinaryOperationType.Assign" /> || /// <see cref="IsModifyAssign(LSLBinaryOperationType)" />) /// </summary> /// <param name="type">The <see cref="LSLBinaryOperationType" /> to test.</param> /// <returns> /// True if the provided <see cref="LSLBinaryOperationType" /> is either a direct assignment operation, or is a /// modifying assignment operation. False if otherwise. /// </returns> public static bool IsAssignOrModifyAssign(this LSLBinaryOperationType type) { return(type == LSLBinaryOperationType.Assign || IsModifyAssign(type)); }
private void AddBinaryOperation(LSLType left, LSLBinaryOperationType operation, LSLType right, LSLType result) { _operations.Add(left + operation.ToOperatorString() + right, result); }
/// <summary> /// Validates and returns the type resulting from a binary operation. /// </summary> /// <param name="left">The expression to on the left of the binary operation.</param> /// <param name="operation">The binary operation to preform.</param> /// <param name="right">The expression to on the right of the binary operation.</param> /// <returns>An <see cref="LSLExpressionValidatorResult" /> object</returns> /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is <c>null</c>.</exception> public LSLExpressionValidatorResult ValidateBinaryOperation(ILSLReadOnlyExprNode left, LSLBinaryOperationType operation, ILSLReadOnlyExprNode right) { if (left == null) { throw new ArgumentNullException("left"); } if (right == null) { throw new ArgumentNullException("right"); } if (left.HasErrors || right.HasErrors) { return(LSLExpressionValidatorResult.Error); } if (left.Type == LSLType.List && operation == LSLBinaryOperationType.AddAssign) { return(LSLExpressionValidatorResult.List); } if (left.Type == LSLType.List || right.Type == LSLType.List) { if (operation == LSLBinaryOperationType.Add) { return(LSLExpressionValidatorResult.List); } } if (left.Type == LSLType.List && right.Type == LSLType.List) { if (operation == LSLBinaryOperationType.Equals || operation == LSLBinaryOperationType.NotEquals) { return(LSLExpressionValidatorResult.Integer); } if (operation == LSLBinaryOperationType.Assign) { return(LSLExpressionValidatorResult.List); } } LSLType t; if (_operations.TryGetValue(left.Type + operation.ToOperatorString() + right.Type, out t)) { return(new LSLExpressionValidatorResult(t, true)); } return(new LSLExpressionValidatorResult(t, false)); }