public virtual Expr Gt(Expr lhs, Expr rhs) { return(UB.Gt(lhs, rhs)); }
public override Expr VisitNAryExpr(NAryExpr node) { // Need to duplicate arguments first (doing post order traversal) var newArgs = new List <Expr>(); foreach (var oldExpr in node.Args) { var newExpr = (Expr)this.Visit(oldExpr); newArgs.Add(newExpr); } // Now can finally duplicate this node now we've done our children if (node.Fun is FunctionCall) { var FC = (FunctionCall)node.Fun; string bvbuiltin = QKeyValue.FindStringAttribute(FC.Func.Attributes, "bvbuiltin"); if (bvbuiltin != null) { return(HandleBvBuiltIns(FC, bvbuiltin, newArgs)); } else { string builtin = QKeyValue.FindStringAttribute(FC.Func.Attributes, "builtin"); if (builtin != null) { return(HandleBuiltIns(FC, builtin, newArgs)); } } // Not a builtin so treat as uninterpreted function call return(Builder.UFC(FC, newArgs.ToArray())); } else if (node.Fun is UnaryOperator) { var U = (UnaryOperator)node.Fun; Debug.Assert(newArgs.Count == 1); switch (U.Op) { case UnaryOperator.Opcode.Neg: return(Builder.Neg(newArgs[0])); case UnaryOperator.Opcode.Not: return(Builder.Not(newArgs[0])); default: throw new NotImplementedException("Unary operator not supported"); } } else if (node.Fun is BinaryOperator) { var B = (BinaryOperator)node.Fun; Debug.Assert(newArgs.Count == 2); switch (B.Op) { // Integer or Real number operators case BinaryOperator.Opcode.Add: return(Builder.Add(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Sub: return(Builder.Sub(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Mul: return(Builder.Mul(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Div: return(Builder.Div(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Mod: return(Builder.Mod(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.RealDiv: return(Builder.RealDiv(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Pow: return(Builder.Pow(newArgs[0], newArgs[1])); // Comparision operators case BinaryOperator.Opcode.Eq: return(Builder.Eq(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Neq: return(Builder.NotEq(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Gt: return(Builder.Gt(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Ge: return(Builder.Ge(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Lt: return(Builder.Lt(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Le: return(Builder.Le(newArgs[0], newArgs[1])); // Bool operators case BinaryOperator.Opcode.And: return(Builder.And(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Or: return(Builder.Or(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Imp: return(Builder.Imp(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Iff: return(Builder.Iff(newArgs[0], newArgs[1])); case BinaryOperator.Opcode.Subtype: throw new NotImplementedException("SubType binary operator support not implemented"); default: throw new NotSupportedException("Binary operator" + B.Op.ToString() + "not supported!"); } } else if (node.Fun is MapStore) { Debug.Assert(newArgs.Count >= 3); // FIXME: We're probably making too many lists/arrays here var map = newArgs[0]; var value = newArgs[newArgs.Count - 1]; // Last argument is value to store var indices = new List <Expr>(); for (int index = 1; index < newArgs.Count - 1; ++index) { indices.Add(newArgs[index]); } Debug.Assert(indices.Count + 2 == newArgs.Count); return(Builder.MapStore(map, value, indices.ToArray())); } else if (node.Fun is MapSelect) { // FIXME: We're probably making too many lists/arrays here Debug.Assert(newArgs.Count >= 2); var map = newArgs[0]; var indices = new List <Expr>(); for (int index = 1; index < newArgs.Count; ++index) { indices.Add(newArgs[index]); } Debug.Assert(indices.Count + 1 == newArgs.Count); return(Builder.MapSelect(map, indices.ToArray())); } else if (node.Fun is IfThenElse) { Debug.Assert(newArgs.Count == 3); return(Builder.IfThenElse(newArgs[0], newArgs[1], newArgs[2])); } else if (node.Fun is TypeCoercion) { // FIXME: Add support for this in the builder // I don't want to put this into the IExprBuilder until I know // exactly how this operator works and how it should be type checked var immutableTC = new NAryExpr(Token.NoToken, node.Fun, newArgs, /*immutable=*/ true); immutableTC.Type = node.Type; return(immutableTC); } else if (node.Fun is ArithmeticCoercion) { Debug.Assert(newArgs.Count == 1); var ac = node.Fun as ArithmeticCoercion; return(Builder.ArithmeticCoercion(ac.Coercion, newArgs[0])); } throw new NotSupportedException("Unsupported NAryExpr"); }