private static DataValueType DecideValueType(BinaryExpressionOperator op, DataValueType left, DataValueType right) { if (op.IsArithmetic()) { if (left == DataValueType.Integer && right == DataValueType.Integer) { return(DataValueType.Integer); } else if (left == DataValueType.Boolean && right == DataValueType.Boolean) { return(DataValueType.Boolean); } else if (left == DataValueType.Float || right == DataValueType.Float) { return(DataValueType.Float); } else if (left == DataValueType.String || right == DataValueType.String) { return(DataValueType.String); } } else if (op.IsLogical() || op.IsRelational()) { return(DataValueType.Boolean); } return(DataValueType.Unknown); }
public RedILNode VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, State data) { var operand = CastUtilities.CastRedILNode <ExpressionNode>(unaryOperatorExpression.Expression.AcceptVisitor(this, data.NewState(unaryOperatorExpression, null))); if (OperatorUtilities.IsIncrement(unaryOperatorExpression.Operator)) { if (data.ParentNode.NodeType != NodeType.Statement) { throw new RedILException($"Incremental operators can only be used within statements"); } BinaryExpressionOperator binaryOp = default; switch (unaryOperatorExpression.Operator) { case UnaryOperatorType.Increment: case UnaryOperatorType.PostIncrement: binaryOp = BinaryExpressionOperator.Add; break; case UnaryOperatorType.Decrement: case UnaryOperatorType.PostDecrement: binaryOp = BinaryExpressionOperator.Subtract; break; } var constantOne = new ConstantValueNode(DataValueType.Integer, 1); return(new AssignNode(operand, VisitBinaryOperatorExpression(operand, constantOne, binaryOp, data.NewState(unaryOperatorExpression, null)))); } var op = OperatorUtilities.UnaryOperator(unaryOperatorExpression.Operator); return(new UnaryExpressionNode(op, operand)); }
public static ExpressionNode Create(BinaryExpressionOperator op, ExpressionNode left, ExpressionNode right) { var type = DecideValueType(op, left.DataType, right.DataType); var node = new BinaryExpressionNode(type, op, left, right); return(node.Simplify()); }
public static bool IsArithmatic(BinaryExpressionOperator op) { return(op == BinaryExpressionOperator.Add || op == BinaryExpressionOperator.Subtract || op == BinaryExpressionOperator.Multiply || op == BinaryExpressionOperator.Divide || op == BinaryExpressionOperator.Modulus); }
/// <summary> /// Creates a new operator expression. /// </summary> /// <param name="operatorType">Type of the operator.</param> /// <param name="left">The left expression.</param> /// <param name="right">The right expression.</param> public BinaryOperatorExpression( BinaryExpressionOperator operatorType, IConditionExpression left, IConditionExpression right) { _operatorType = operatorType; _left = left; _right = right; }
public UniformOperatorNode( DataValueType dataType, BinaryExpressionOperator op, IList <ExpressionNode> children) : base(RedILNodeType.UniformExpression, dataType) { Operator = op; Children = children; }
public static bool IsBoolean(BinaryExpressionOperator op) { return(op == BinaryExpressionOperator.And || op == BinaryExpressionOperator.Or || op == BinaryExpressionOperator.Equal || op == BinaryExpressionOperator.NotEqual || op == BinaryExpressionOperator.Less || op == BinaryExpressionOperator.Greater || op == BinaryExpressionOperator.LessEqual || op == BinaryExpressionOperator.GreaterEqual); }
public BinaryExpressionNode( DataValueType dataType, BinaryExpressionOperator op, ExpressionNode left, ExpressionNode right) : base(RedILNodeType.BinaryExpression, dataType) { Operator = op; Left = left; Right = right; }
private ExpressionNode SimplifyArithmatic(BinaryExpressionOperator op, ExpressionNode left, ExpressionNode right) { if (left.Type == RedILNodeType.Constant && right.Type == RedILNodeType.Constant) { var leftC = (ConstantValueNode)left; var rightC = (ConstantValueNode)right; var isInteger = left.DataType == DataValueType.Integer && right.DataType == DataValueType.Integer; var dataType = isInteger ? DataValueType.Integer : DataValueType.Float; var leftVal = isInteger ? Convert.ToInt64(leftC.Value) : Convert.ToDouble(leftC.Value); var rightVal = isInteger ? Convert.ToInt64(rightC.Value) : Convert.ToDouble(rightC.Value); switch (Operator) { case BinaryExpressionOperator.Add: return(new ConstantValueNode(dataType, leftVal + rightVal)); case BinaryExpressionOperator.Subtract: return(new ConstantValueNode(dataType, leftVal - rightVal)); case BinaryExpressionOperator.Multiply: return(new ConstantValueNode(dataType, leftVal * rightVal)); case BinaryExpressionOperator.Divide: return(new ConstantValueNode(dataType, leftVal / rightVal)); case BinaryExpressionOperator.Modulus: return(new ConstantValueNode(dataType, leftVal % rightVal)); case BinaryExpressionOperator.Less: return(new ConstantValueNode(DataValueType.Boolean, leftVal < rightVal)); case BinaryExpressionOperator.Greater: return(new ConstantValueNode(DataValueType.Boolean, leftVal > rightVal)); case BinaryExpressionOperator.LessEqual: return(new ConstantValueNode(DataValueType.Boolean, leftVal <= rightVal)); case BinaryExpressionOperator.GreaterEqual: return(new ConstantValueNode(DataValueType.Boolean, leftVal >= rightVal)); } } return(this); }
private ExpressionNode SimplifyBoolean(BinaryExpressionOperator op, ExpressionNode left, ExpressionNode right) { if (left.Type == RedILNodeType.Constant || right.Type == RedILNodeType.Constant) { var constant = left.Type == RedILNodeType.Constant ? (ConstantValueNode)left : (ConstantValueNode)right; var other = left.Type == RedILNodeType.Constant ? right : left; switch (op) { case BinaryExpressionOperator.And: return(constant.Value.Equals(true) ? other : False); case BinaryExpressionOperator.Or: return(constant.Value.Equals(true) ? True : other); } } return(this); }
internal static SmallType GetResultType(SmallType pLeft, BinaryExpressionOperator pOp, SmallType pRight) { switch (pOp) { case BinaryExpressionOperator.Addition: case BinaryExpressionOperator.Subtraction: case BinaryExpressionOperator.Multiplication: case BinaryExpressionOperator.Division: case BinaryExpressionOperator.Mod: if (pLeft.IsAssignableFrom(pRight)) { return(pLeft); } if (TypeHelper.IsFloat(pLeft) && TypeHelper.IsNumber(pRight)) { return(pLeft); } if (TypeHelper.IsFloat(pRight) && TypeHelper.IsNumber(pLeft)) { return(pRight); } return(SmallTypeCache.Undefined); case BinaryExpressionOperator.Equals: case BinaryExpressionOperator.GreaterThan: case BinaryExpressionOperator.GreaterThanOrEqual: case BinaryExpressionOperator.LessThan: case BinaryExpressionOperator.LessThanOrEqual: case BinaryExpressionOperator.NotEquals: if (pLeft.IsAssignableFrom(pRight)) { return(pLeft); } return(SmallTypeCache.Undefined); default: throw new NotSupportedException("Unknown binary expression operator " + pOp.ToString()); } }
/// <summary> /// Creates a new operator expression. /// </summary> /// <param name="operatorType">Binary expression operator type.</param> public OperatorExpressionPlaceholder(BinaryExpressionOperator operatorType) { _operatorType = operatorType; }
/// <summary> /// Takes in a list of expressions and operator expression placeholders and /// builds an expression tree node. /// </summary> /// <param name="originalNodes">Original nodes.</param> /// <param name="originalExpression">Original expression.</param> /// <returns>A condition expression.</returns> private static IConditionExpression AssembleExpressionTree( ReadOnlyCollection <IConditionExpression> originalNodes, string originalExpression) { IConditionExpression conditionExpression = null; List <IConditionExpression> nodes = new List <IConditionExpression>(originalNodes); // // Build a queue that represents the binary operator precedence // Queue <BinaryExpressionOperator> operatorPrecedence = new Queue <BinaryExpressionOperator>(); operatorPrecedence.Enqueue(BinaryExpressionOperator.Equal); operatorPrecedence.Enqueue(BinaryExpressionOperator.NotEqual); operatorPrecedence.Enqueue(BinaryExpressionOperator.Contains); operatorPrecedence.Enqueue(BinaryExpressionOperator.Matches); operatorPrecedence.Enqueue(BinaryExpressionOperator.And); operatorPrecedence.Enqueue(BinaryExpressionOperator.Or); // // Loop through the nodes and merge them by operator precedence // BinaryExpressionOperator currentOperator = operatorPrecedence.Dequeue(); while (nodes.Count > 1) { for (int nodeIndex = 1; nodeIndex < nodes.Count - 1; nodeIndex++) { OperatorExpressionPlaceholder operatorExpressionPlaceHolder = nodes[nodeIndex] as OperatorExpressionPlaceholder; if (operatorExpressionPlaceHolder != null && operatorExpressionPlaceHolder.Operator == currentOperator) { IConditionExpression left = nodes[nodeIndex - 1]; IConditionExpression right = nodes[nodeIndex + 1]; if ((operatorExpressionPlaceHolder.Operator == BinaryExpressionOperator.Equal || operatorExpressionPlaceHolder.Operator == BinaryExpressionOperator.Contains) && !(left is LeafExpression && right is LeafExpression)) { OnInvalidExpression(originalExpression); } BinaryOperatorExpression operatorExpression = new BinaryOperatorExpression( operatorExpressionPlaceHolder.Operator, left, right); nodes[nodeIndex] = operatorExpression; nodes.Remove(left); nodes.Remove(right); // // Restart processing of this level // nodeIndex = 0; } } if (operatorPrecedence.Count > 0) { currentOperator = operatorPrecedence.Dequeue(); } else { break; } } // // At the end of everything, we should have a single binary or unary // condition expression. Anything else is invalid and a format exception // will be thrown. // if (nodes.Count == 1) { conditionExpression = nodes[0] as BinaryOperatorExpression; if (conditionExpression == null) { conditionExpression = nodes[0] as UnaryOperatorExpression; } } if (conditionExpression == null) { OnInvalidExpression(originalExpression); } return(conditionExpression); }
private ExpressionNode VisitBinaryOperatorExpression(ExpressionNode left, ExpressionNode right, BinaryExpressionOperator op, State data) { if (OperatorUtilities.IsBoolean(op)) { return(new BinaryExpressionNode(DataValueType.Boolean, op, left, right)); } else if (OperatorUtilities.IsArithmatic(op)) { if (left.DataType == DataValueType.String || right.DataType == DataValueType.String) { return(new BinaryExpressionNode(DataValueType.String, BinaryExpressionOperator.StringConcat, left, right)); } else if (left.DataType == DataValueType.Float || right.DataType == DataValueType.Float) { return(new BinaryExpressionNode(DataValueType.Float, op, left, right)); } else if (left.DataType == DataValueType.Integer && right.DataType == DataValueType.Integer) { return(new BinaryExpressionNode(DataValueType.Integer, op, left, right)); } } else if (op == BinaryExpressionOperator.NullCoalescing) { return(new BinaryExpressionNode(left.DataType, op, left, right)); } throw new RedILException($"Unsupported operator '{op}' with data types '{left.DataType}' and '{right.DataType}'"); }
public static BinaryExpressionSyntax BinaryExpression(SyntaxNode pLeft, BinaryExpressionOperator pOperator, SyntaxNode pRight) { return(new BinaryExpressionSyntax(pLeft, pOperator, pRight)); }
internal BinaryExpressionSyntax(SyntaxNode pLeft, BinaryExpressionOperator pOperator, SyntaxNode pRight) { Left = pLeft; Operator = pOperator; Right = pRight; }
public static bool IsLogical(this BinaryExpressionOperator op) { return(op == BinaryExpressionOperator.And || op == BinaryExpressionOperator.Or); }
private void WriteBinaryOperator(CompilationState state, BinaryExpressionOperator op) { switch (op) { case BinaryExpressionOperator.StringConcat: state.Write(".."); break; case BinaryExpressionOperator.Add: state.Write("+"); break; case BinaryExpressionOperator.Subtract: state.Write("-"); break; case BinaryExpressionOperator.Multiply: state.Write("*"); break; case BinaryExpressionOperator.Divide: state.Write("/'"); break; case BinaryExpressionOperator.Modulus: state.Write("%"); break; case BinaryExpressionOperator.Equal: state.Write("=="); break; case BinaryExpressionOperator.Less: state.Write("<"); break; case BinaryExpressionOperator.Greater: state.Write(">"); break; case BinaryExpressionOperator.NotEqual: state.Write("~="); break; case BinaryExpressionOperator.LessEqual: state.Write("<="); break; case BinaryExpressionOperator.GreaterEqual: state.Write(">="); break; case BinaryExpressionOperator.Or: case BinaryExpressionOperator.NullCoalescing: state.Write(" or "); break; case BinaryExpressionOperator.And: state.Write(" and "); break; } }
public override LLVMValueRef Emit(EmittingContext pContext) { pContext.EmitDebugLocation(this); LLVMValueRef value; switch (Operator) { case UnaryExpressionOperator.Not: value = Value.Emit(pContext); Utils.LlvmHelper.LoadIfPointer(ref value, pContext); return(LLVM.BuildNot(pContext.Builder, value, "")); case UnaryExpressionOperator.Negative: value = Value.Emit(pContext); Utils.LlvmHelper.LoadIfPointer(ref value, pContext); return(LLVM.BuildNeg(pContext.Builder, value, "")); case UnaryExpressionOperator.Length: var arr = Value.Emit(pContext); return(LLVM.BuildLoad(pContext.Builder, pContext.GetArrayLength(arr), "")); case UnaryExpressionOperator.PreIncrement: case UnaryExpressionOperator.PreDecrement: case UnaryExpressionOperator.PostIncrement: case UnaryExpressionOperator.PostDecrement: var variable = (IdentifierSyntax)Value; variable.DoNotLoad = true; LLVMValueRef v = variable.Emit(pContext); BinaryExpressionOperator op = BinaryExpressionOperator.Equals; switch (Operator) { case UnaryExpressionOperator.PostDecrement: case UnaryExpressionOperator.PreDecrement: op = BinaryExpressionOperator.Subtraction; break; case UnaryExpressionOperator.PostIncrement: case UnaryExpressionOperator.PreIncrement: op = BinaryExpressionOperator.Addition; break; } value = BinaryExpressionSyntax.EmitOperator(v, op, pContext.GetInt(1), pContext); //Post unary we want to return the original variable value if (Operator == UnaryExpressionOperator.PostIncrement || Operator == UnaryExpressionOperator.PostDecrement) { //Save the old value to a temp variable that we will return var temp = pContext.AllocateVariable("<temp_unary>", Value); LLVMValueRef tempValue = Utils.LlvmHelper.IsPointer(v) ? LLVM.BuildLoad(pContext.Builder, v, "") : v; LLVM.BuildStore(pContext.Builder, tempValue, temp); //Increment the variable Utils.LlvmHelper.LoadIfPointer(ref value, pContext); if (Value.SyntaxType == SyntaxType.Identifier || Value.SyntaxType == SyntaxType.MemberAccess) { LLVM.BuildStore(pContext.Builder, value, v); } return(temp); } //If it isn't a variable we cane save we need to return the addition if (Value.SyntaxType == SyntaxType.Identifier || Value.SyntaxType == SyntaxType.MemberAccess) { LLVM.BuildStore(pContext.Builder, value, v); } return(value); default: throw new NotSupportedException(); } }
internal static LLVMValueRef EmitOperator(LLVMValueRef pLeft, BinaryExpressionOperator pOp, LLVMValueRef pRight, EmittingContext pContext) { //We since arrays are pointers, we need to load the value at the pointer LlvmHelper.LoadIfPointer(ref pLeft, pContext); LlvmHelper.LoadIfPointer(ref pRight, pContext); bool useFloat = false; if (LlvmHelper.IsFloat(pLeft)) { if (!LlvmHelper.IsFloat(pRight)) { pRight = LLVM.BuildSIToFP(pContext.Builder, pRight, pLeft.TypeOf(), ""); } useFloat = true; } if (LlvmHelper.IsFloat(pRight)) { if (!LlvmHelper.IsFloat(pLeft)) { pLeft = LLVM.BuildSIToFP(pContext.Builder, pLeft, pRight.TypeOf(), ""); } useFloat = true; } switch (pOp) { case BinaryExpressionOperator.Addition: if (useFloat) { return(LLVM.BuildFAdd(pContext.Builder, pLeft, pRight, "")); } else { return(LLVM.BuildAdd(pContext.Builder, pLeft, pRight, "")); } case BinaryExpressionOperator.Multiplication: if (useFloat) { return(LLVM.BuildFMul(pContext.Builder, pLeft, pRight, "")); } else { return(LLVM.BuildMul(pContext.Builder, pLeft, pRight, "")); } case BinaryExpressionOperator.Subtraction: if (useFloat) { return(LLVM.BuildFSub(pContext.Builder, pLeft, pRight, "")); } else { return(LLVM.BuildSub(pContext.Builder, pLeft, pRight, "")); } case BinaryExpressionOperator.Division: if (useFloat) { return(LLVM.BuildFDiv(pContext.Builder, pLeft, pRight, "")); } else { return(LLVM.BuildSDiv(pContext.Builder, pLeft, pRight, "")); } case BinaryExpressionOperator.Mod: if (useFloat) { return(LLVM.BuildFRem(pContext.Builder, pLeft, pRight, "")); } else { return(LLVM.BuildSRem(pContext.Builder, pLeft, pRight, "")); } case BinaryExpressionOperator.Equals: if (useFloat) { return(LLVM.BuildFCmp(pContext.Builder, LLVMRealPredicate.LLVMRealOEQ, pLeft, pRight, "")); } else { return(LLVM.BuildICmp(pContext.Builder, LLVMIntPredicate.LLVMIntEQ, pLeft, pRight, "")); } case BinaryExpressionOperator.NotEquals: if (useFloat) { return(LLVM.BuildFCmp(pContext.Builder, LLVMRealPredicate.LLVMRealONE, pLeft, pRight, "")); } else { return(LLVM.BuildICmp(pContext.Builder, LLVMIntPredicate.LLVMIntNE, pLeft, pRight, "")); } case BinaryExpressionOperator.GreaterThan: if (useFloat) { return(LLVM.BuildFCmp(pContext.Builder, LLVMRealPredicate.LLVMRealOGT, pLeft, pRight, "")); } else { return(LLVM.BuildICmp(pContext.Builder, LLVMIntPredicate.LLVMIntSGT, pLeft, pRight, "")); } case BinaryExpressionOperator.GreaterThanOrEqual: if (useFloat) { return(LLVM.BuildFCmp(pContext.Builder, LLVMRealPredicate.LLVMRealOGE, pLeft, pRight, "")); } else { return(LLVM.BuildICmp(pContext.Builder, LLVMIntPredicate.LLVMIntSGE, pLeft, pRight, "")); } case BinaryExpressionOperator.LessThan: if (useFloat) { return(LLVM.BuildFCmp(pContext.Builder, LLVMRealPredicate.LLVMRealOLT, pLeft, pRight, "")); } else { return(LLVM.BuildICmp(pContext.Builder, LLVMIntPredicate.LLVMIntSLT, pLeft, pRight, "")); } case BinaryExpressionOperator.LessThanOrEqual: if (useFloat) { return(LLVM.BuildFCmp(pContext.Builder, LLVMRealPredicate.LLVMRealOLE, pLeft, pRight, "")); } else { return(LLVM.BuildICmp(pContext.Builder, LLVMIntPredicate.LLVMIntSLE, pLeft, pRight, "")); } case BinaryExpressionOperator.And: case BinaryExpressionOperator.BitwiseAnd: return(LLVM.BuildAnd(pContext.Builder, pLeft, pRight, "")); case BinaryExpressionOperator.Or: case BinaryExpressionOperator.BitwiseOr: return(LLVM.BuildOr(pContext.Builder, pLeft, pRight, "")); case BinaryExpressionOperator.LeftBitShift: return(LLVM.BuildLShr(pContext.Builder, pLeft, pRight, "")); case BinaryExpressionOperator.RightBitShift: return(LLVM.BuildAShr(pContext.Builder, pLeft, pRight, "")); default: throw new NotImplementedException(); } }
public static bool IsRelational(this BinaryExpressionOperator op) { return(op == BinaryExpressionOperator.Equal || op == BinaryExpressionOperator.NotEqual || op == BinaryExpressionOperator.Less || op == BinaryExpressionOperator.LessEqual || op == BinaryExpressionOperator.Greater || op == BinaryExpressionOperator.GreaterEqual); }