public virtual void Visit(ChainingExpression chainingExpression)
 {
     foreach (var operand in chainingExpression.Operands)
     {
         Visit(operand);
     }
 }
        public string GenerateConditionString(ChainingExpression expression, IDictionary <string, string> rename)
        {
            var bob = new StringBuilder();

            int i;

            for (i = 0; i < expression.Operators.Count; i++)
            {
                var operand = GenerateConditionString(expression.Operands[i], rename);
                var op      = GenerateString(expression.Operators[i]);
                bob.Append(operand + " " + op + " ");
            }
            var last = GenerateConditionString(expression.Operands[i], rename);

            bob.Append(last);

            return(bob.ToString());
        }
Esempio n. 3
0
        void RelationalExpression(out Expression e, bool allowSemi, bool allowLambda)
        {
            Contract.Ensures(Contract.ValueAtReturn(out e) != null);
            IToken x, firstOpTok = null;  Expression e0, e1, acc = null;  BinaryExpr.Opcode op;
            List<Expression> chain = null;
            List<BinaryExpr.Opcode> ops = null;
            List<Expression/*?*/> prefixLimits = null;
            Expression k;
            int kind = 0;  // 0 ("uncommitted") indicates chain of ==, possibly with one !=
                      // 1 ("ascending")   indicates chain of ==, <, <=, possibly with one !=
                      // 2 ("descending")  indicates chain of ==, >, >=, possibly with one !=
                      // 3 ("illegal")     indicates illegal chain
                      // 4 ("disjoint")    indicates chain of disjoint set operators
            bool hasSeenNeq = false;

            Term(out e0, allowSemi, allowLambda);
            e = e0;
            if (IsRelOp()) {
            RelOp(out x, out op, out k);
            firstOpTok = x;
            Term(out e1, allowSemi, allowLambda);
            if (k == null) {
             e = new BinaryExpr(x, op, e0, e1);
             if (op == BinaryExpr.Opcode.Disjoint)
               acc = new BinaryExpr(x, BinaryExpr.Opcode.Add, e0, e1); // accumulate first two operands.
            } else {
             Contract.Assert(op == BinaryExpr.Opcode.Eq || op == BinaryExpr.Opcode.Neq);
             e = new TernaryExpr(x, op == BinaryExpr.Opcode.Eq ? TernaryExpr.Opcode.PrefixEqOp : TernaryExpr.Opcode.PrefixNeqOp, k, e0, e1);
            }

            while (IsRelOp()) {
                if (chain == null) {
                 chain = new List<Expression>();
                 ops = new List<BinaryExpr.Opcode>();
                 prefixLimits = new List<Expression>();
                 chain.Add(e0);  ops.Add(op);  prefixLimits.Add(k);  chain.Add(e1);
                 switch (op) {
                   case BinaryExpr.Opcode.Eq:
                     kind = 0;  break;
                   case BinaryExpr.Opcode.Neq:
                     kind = 0;  hasSeenNeq = true;  break;
                   case BinaryExpr.Opcode.Lt:
                   case BinaryExpr.Opcode.Le:
                     kind = 1;  break;
                   case BinaryExpr.Opcode.Gt:
                   case BinaryExpr.Opcode.Ge:
                     kind = 2;  break;
                   case BinaryExpr.Opcode.Disjoint:
                     kind = 4;  break;
                   default:
                     kind = 3;  break;
                 }
                }
                e0 = e1;

                RelOp(out x, out op, out k);
                switch (op) {
                 case BinaryExpr.Opcode.Eq:
                   if (kind != 0 && kind != 1 && kind != 2) { SemErr(x, "chaining not allowed from the previous operator"); }
                   break;
                 case BinaryExpr.Opcode.Neq:
                   if (hasSeenNeq) { SemErr(x, "a chain cannot have more than one != operator"); }
                   if (kind != 0 && kind != 1 && kind != 2) { SemErr(x, "this operator cannot continue this chain"); }
                   hasSeenNeq = true;  break;
                 case BinaryExpr.Opcode.Lt:
                 case BinaryExpr.Opcode.Le:
                   if (kind == 0) { kind = 1; }
                   else if (kind != 1) { SemErr(x, "this operator chain cannot continue with an ascending operator"); }
                   break;
                 case BinaryExpr.Opcode.Gt:
                 case BinaryExpr.Opcode.Ge:
                   if (kind == 0) { kind = 2; }
                   else if (kind != 2) { SemErr(x, "this operator chain cannot continue with a descending operator"); }
                   break;
                 case BinaryExpr.Opcode.Disjoint:
                   if (kind != 4) { SemErr(x, "can only chain disjoint (!!) with itself."); kind = 3; }
                   break;
                 default:
                   SemErr(x, "this operator cannot be part of a chain");
                   kind = 3;  break;
                }

                Term(out e1, allowSemi, allowLambda);
                ops.Add(op); prefixLimits.Add(k); chain.Add(e1);
                if (k != null) {
                 Contract.Assert(op == BinaryExpr.Opcode.Eq || op == BinaryExpr.Opcode.Neq);
                 e = new TernaryExpr(x, op == BinaryExpr.Opcode.Eq ? TernaryExpr.Opcode.PrefixEqOp : TernaryExpr.Opcode.PrefixNeqOp, k, e0, e1);
                } else if (op == BinaryExpr.Opcode.Disjoint && acc != null) {  // the second conjunct always holds for legal programs
                 e = new BinaryExpr(x, BinaryExpr.Opcode.And, e, new BinaryExpr(x, op, acc, e1));
                 acc = new BinaryExpr(x, BinaryExpr.Opcode.Add, acc, e1); //e0 has already been added.
                } else {
                 e = new BinaryExpr(x, BinaryExpr.Opcode.And, e, new BinaryExpr(x, op, e0, e1));
                }

            }
            }
            if (chain != null) {
             e = new ChainingExpression(firstOpTok, chain, ops, prefixLimits, e);
            }
        }
Esempio n. 4
0
        public Expression TreeToExpression()
        {
            Contract.Ensures(Contract.Result <Expression>() != null);
            if (IsLeaf())
            {
                return(Data);
            }
            if (Data is TacnyBinaryExpr)
            {
                TacnyBinaryExpr bexp = (TacnyBinaryExpr)Data;
                Expression      E0   = LChild.TreeToExpression();
                Expression      E1   = RChild?.TreeToExpression();
                return(new TacnyBinaryExpr(bexp.tok, bexp.Op, E0, E1));
            }
            if (Data is BinaryExpr)
            {
                BinaryExpr bexp = (BinaryExpr)Data;
                Expression E0   = LChild.TreeToExpression();
                Expression E1   = RChild?.TreeToExpression();

                return(new BinaryExpr(bexp.tok, bexp.Op, E0, E1));
            }
            if (Data is ChainingExpression)
            {
                List <Expression>  operands = null;
                ChainingExpression ce       = (ChainingExpression)Data;
                operands = GetLeafData();
                operands.RemoveAt(1); // hack to remove the duplicate name statement
                List <BinaryExpr.Opcode> operators = new List <BinaryExpr.Opcode>();
                BinaryExpr expr = (BinaryExpr)LChild.TreeToExpression();
                operators.Add(((BinaryExpr)expr.E0).Op);
                operators.Add(((BinaryExpr)expr.E1).Op);
                return(new ChainingExpression(ce.tok, operands, operators, ce.PrefixLimits, expr));
            }
            if (Data is ParensExpression)
            {
                return(new ParensExpression(Data.tok, LChild.TreeToExpression()));
            }
            if (Data is QuantifierExpr)
            {
                QuantifierExpr qexp = (QuantifierExpr)Data;

                if (Data is ForallExpr)
                {
                    return(new ForallExpr(qexp.tok, qexp.BoundVars, qexp.Range, LChild.TreeToExpression(),
                                          qexp.Attributes));
                }
                if (Data is ExistsExpr)
                {
                    return(new ExistsExpr(qexp.tok, qexp.BoundVars, qexp.Range, LChild.TreeToExpression(),
                                          qexp.Attributes));
                }
            }
            else if (Data is NegationExpression)
            {
                return(new NegationExpression(Data.tok, LChild.TreeToExpression()));
            }
            else if (Data is SeqSelectExpr)
            {
                var e = (SeqSelectExpr)Data;
                return(new SeqSelectExpr(e.tok, e.SelectOne, e.Seq, LChild.TreeToExpression(),
                                         RChild?.TreeToExpression()));
            }

            return(Data);
        }