< Summary

Class:NanoCLang.Entities.RelationalExpression
Assembly:NanoCLang
File(s):C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\Expression\PureExpression\BinaryExpression\RelationalExpression.cs
Covered lines:43
Uncovered lines:7
Coverable lines:50
Total lines:111
Line coverage:86% (43 of 50)
Covered branches:33
Total branches:46
Branch coverage:71.7% (33 of 46)

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
.ctor(...)91.66%1290.9%
GetOperator(...)85.71%788.88%
Replace(...)100%1100%
DoInferType(...)37.5%1666.66%
ToBoolean(...)85.71%788.88%
Equality(...)100%4100%

File(s)

C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\Expression\PureExpression\BinaryExpression\RelationalExpression.cs

#LineLine coverage
 1using Microsoft.Z3;
 2using NanoCLang.Environemnts;
 3using System;
 4
 5namespace NanoCLang.Entities {
 6    /// <summary>
 7    /// Provides a class for relation expressions.
 8    /// </summary>
 9    public class RelationalExpression : BinaryExpression {
 10        private readonly RelOperator @operator;
 11        /// <summary>
 12        /// Creates a new instance of a relation expression of <paramref name="left"/> and <paramref name="right"/>.
 13        /// </summary>
 14        /// <param name="left">Left hand operand.</param>
 15        /// <param name="op">Operator to apply</param>
 16        /// <param name="right">Right hand operand.</param>
 272417        public RelationalExpression(PureExpression left, RelOperator op, PureExpression right) : base(left, GetOperator(
 136218            @operator = op;
 136219        }
 20
 21        /// <summary>
 22        /// Creates a new instance of a relation expression of <paramref name="left"/> and <paramref name="right"/>.
 23        /// </summary>
 24        /// <param name="left">Left hand operand.</param>
 25        /// <param name="op">Operator to apply</param>
 26        /// <param name="right">Right hand operand.</param>
 24227        public RelationalExpression(PureExpression left, string op, PureExpression right) : base(left, op, right) {
 12128            @operator = op switch {
 2829                "<" => RelOperator.Less,
 3830                ">" => RelOperator.Greater,
 231                "<=" => RelOperator.LessEqual,
 1832                ">=" => RelOperator.GreaterEqual,
 3433                "==" => RelOperator.Equal,
 134                "!=" => RelOperator.Unequal,
 035                _ => throw new ArgumentOutOfRangeException("Invalid relational operator!")
 12136            };
 12137        }
 38
 39        /// <summary>
 40        /// Enumeration of valid relational operators.
 41        /// </summary>
 42        public enum RelOperator {
 43            /// <summary>
 44            /// Strictly less than operator.
 45            /// </summary>
 46            Less,
 47            /// <summary>
 48            /// Strictly greater than operator.
 49            /// </summary>
 50            Greater,
 51            /// <summary>
 52            /// Less or equal to operator.
 53            /// </summary>
 54            LessEqual,
 55            /// <summary>
 56            /// Greater or equal to operator.
 57            /// </summary>
 58            GreaterEqual,
 59            /// <summary>
 60            /// Equality operator.
 61            /// </summary>
 62            Equal,
 63            /// <summary>
 64            /// Inequality operator
 65            /// </summary>
 66            Unequal
 67        }
 136268        private static string GetOperator(RelOperator op) => op switch {
 5369            RelOperator.Less => "<",
 8970            RelOperator.Greater => ">",
 271            RelOperator.LessEqual => "<=",
 5372            RelOperator.GreaterEqual => ">=",
 114473            RelOperator.Equal => "==",
 2174            RelOperator.Unequal => "!=",
 075            _ => throw new ArgumentOutOfRangeException("Invalid relational operator!")
 136276        };
 77        /// <inheritdoc/>
 78        public override PureExpression Replace(Substitutor sub)
 34279            => new RelationalExpression(Left.Replace(sub), @operator, Right.Replace(sub));
 80        /// <inheritdoc/>
 14281        protected override Type DoInferType(LocalEnvironment gamma) {
 14282            var left = Left.InferType(gamma);
 14283            var right = Right.InferType(gamma);
 84
 14285            switch (left.BaseType) {
 28486            case IntegerType t when right.BaseType is IntegerType o && t.Size == o.Size: break;
 087            case IntegerType _ when right.BaseType is ReferenceType: break;
 088            case ReferenceType _ when right.BaseType is IntegerType: break;
 089            case ReferenceType t when right.BaseType is ReferenceType o && t.Location == o.Location: break;
 090            default: throw new IllFormedException(this, $"Cannot compare {left.BaseType} and {right.BaseType}!");
 91            }
 14292            return new RefinedType(IntegerType.Boolean,
 28493                v => EqualExpression(v, this));
 14294        }
 95        /// <inheritdoc/>
 72096        public override BoolExpr ToBoolean(LocalEnvironment gamma, NanoCSMT smt) => @operator switch {
 16897            RelOperator.Less => smt.Context.MkLt(Left.ToArithmetic(gamma, smt), Right.ToArithmetic(gamma, smt)),
 10598            RelOperator.Greater => smt.Context.MkGt(Left.ToArithmetic(gamma, smt), Right.ToArithmetic(gamma, smt)),
 399            RelOperator.LessEqual => smt.Context.MkLe(Left.ToArithmetic(gamma, smt), Right.ToArithmetic(gamma, smt)),
 71100            RelOperator.GreaterEqual => smt.Context.MkGe(Left.ToArithmetic(gamma, smt), Right.ToArithmetic(gamma, smt)),
 273101            RelOperator.Equal => Equality(gamma, smt),
 100102            RelOperator.Unequal => !Equality(gamma, smt),
 0103            _ => throw new InvalidProgramException("Unexpected operator! Constructor forbids this!")
 720104        };
 373105        private BoolExpr Equality(LocalEnvironment gamma, NanoCSMT smt) {
 373106            return Left.InferType(gamma).BaseType is IntegerType i && i.Size == 1
 373107                ? smt.Context.MkEq(Left.ToBoolean(gamma, smt), Right.ToBoolean(gamma, smt))
 373108                : smt.Context.MkEq(Left.ToArithmetic(gamma, smt), Right.ToArithmetic(gamma, smt));
 373109        }
 110    }
 111}