< Summary

Class:NanoCLang.Entities.TernaryExpression
Assembly:NanoCLang
File(s):C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\Expression\TernaryExpression.cs
Covered lines:64
Uncovered lines:13
Coverable lines:77
Total lines:119
Line coverage:83.1% (64 of 77)
Covered branches:26
Total branches:42
Branch coverage:61.9% (26 of 42)

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
get_Condition()100%1100%
get_Then()100%1100%
get_Else()100%1100%
DoInferWorld(...)30%1073.07%
Tokens()81.81%2291.66%
PrintBody()66.66%680%
Tokens()100%6100%
RequiredFunctions()100%10%
Equals(...)100%1100%
Equals(...)50%6100%
GetHashCode()100%10%
op_Equality(...)100%10%
op_Inequality(...)100%10%

File(s)

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

#LineLine coverage
 1using NanoCLang.Environemnts;
 2using System;
 3using System.Collections.Generic;
 4using System.Linq;
 5
 6namespace NanoCLang.Entities {
 7    /// <summary>
 8    /// Provides a class for ternary expressions.
 9    /// </summary>
 10    public class TernaryExpression : Expression, IEquatable<TernaryExpression?> {
 11        /// <summary>
 12        /// Creates a new ternary expression instance.
 13        /// </summary>
 14        /// <param name="condition">Ternary condition expression.</param>
 15        /// <param name="then">Expression to evaluate if the <paramref name="condition"/> is truthy.</param>
 16        /// <param name="else">Expression to evaluate if the <paramref name="condition"/> is falsy.</param>
 2817        public TernaryExpression(PureExpression condition, Expression then, Expression @else) {
 1418            Condition = condition;
 1419            Then = then;
 1420            Else = @else;
 1421        }
 22        /// <summary>
 23        /// Condition that decides the evaluation of the bodies.
 24        /// </summary>
 4325        public PureExpression Condition { get; }
 26        /// <summary>
 27        /// Expression to evaluate if the <see cref="Condition"/> is truthy.
 28        /// </summary>
 3129        public Expression Then { get; }
 30        /// <summary>
 31        /// Expression to evaluate if the <see cref="Condition"/> is falsy.
 32        /// </summary>
 3133        public Expression Else { get; }
 34        /// <inheritdoc/>
 635        protected override World DoInferWorld(GlobalEnvironment phi, LocalEnvironment gamma, Heap heap) {
 636            var condType = Condition.InferType(gamma);
 637            if (!(condType.BaseType is IntegerType condBase))
 038                throw new IllFormedException(Condition, $"Condition is not boolean nor integral in ternary!");
 639            var thenGuard = PureExpression.UnqualExpression(Condition, new IntegerConstant(0, condBase.Size));
 640            var thenWorld = gamma.Guarded(thenGuard,
 1241                gamma => Then.InferWorld(phi, gamma, heap));
 642            var elseGuard = PureExpression.EqualExpression(Condition, new IntegerConstant(0, condBase.Size));
 643            var elseWorld = gamma.Guarded(elseGuard,
 1244                gamma => Else.InferWorld(phi, gamma, heap));
 45
 646            try {
 647                var returnWorld = new World(
 648                    new RefinedType(BasicType.SuperType(thenWorld.Type.BaseType, elseWorld.Type.BaseType),
 649                        v => (thenGuard & thenWorld.Type.Refinement) | (elseGuard & elseWorld.Type.Refinement)),
 650                    Heap.SuperHeap(gamma, thenWorld.Heap, elseWorld.Heap));
 651                returnWorld.WellFormed(gamma);
 52
 1253                if (gamma.Guarded(thenGuard, gamma => thenWorld.SubWorld(gamma, returnWorld))
 1254                    && gamma.Guarded(elseGuard, gamma => elseWorld.SubWorld(gamma, returnWorld)))
 655                    return returnWorld;
 056            } catch (IllFormedException) { }
 57
 58            // Fallback to default, less sophisticated world checking
 059            return thenWorld.SubWorld(gamma, elseWorld)
 060                ? elseWorld
 061                : elseWorld.SubWorld(gamma, thenWorld)
 062                ? thenWorld
 063                : throw new IllFormedException(Else, "Two branches of the ternary must return the same type!");
 664        }
 65        /// <inheritdoc/>
 666        public override IEnumerable<StringFormatterToken> Tokens(NanoCSourceFormat args) {
 667            yield return "if";
 1268            if (args.NewlinesAfterIf <= 0) yield return " ";
 069            else for (int i = 0; i < args.NewlinesAfterIf; i++) yield return new NewLineToken();
 15670            foreach (var tk in Condition.Tokens(args)) yield return tk;
 671            if (args.NewlinesBeforeThen <= 0) yield return " ";
 3072            else for (int i = 0; i < args.NewlinesBeforeThen; i++) yield return new NewLineToken();
 673            yield return "then";
 27074            foreach (var tk in StringFormatterToken.Indented(args.IfBodyIndent, () => PrintBody(Then, args.NewlinesAfter
 675            if (args.NewlinesBeforeElse <= 0) yield return " ";
 3076            else for (int i = 0; i < args.NewlinesBeforeElse; i++) yield return new NewLineToken();
 677            yield return "else";
 10278            foreach (var tk in StringFormatterToken.Indented(args.IfBodyIndent, () => PrintBody(Else, args.NewlinesAfter
 679        }
 1280        private IEnumerable<StringFormatterToken> PrintBody(Expression expression, int newlines, NanoCSourceFormat args)
 2481            if (newlines <= 0) yield return " ";
 082            else for (int i = 0; i < newlines; i++) yield return new NewLineToken();
 25283            foreach (var tk in expression.Tokens(args)) yield return tk;
 1284        }
 85        /// <inheritdoc/>
 586        public override IEnumerable<StringFormatterToken> Tokens(CSourceFormat args) {
 587            yield return "if (";
 588            args.PureRequiresReturn = false;
 13289            foreach (var tk in Condition.Tokens(args)) yield return tk;
 590            yield return ") {";
 591            yield return new NewLineToken();
 592            args.PureRequiresReturn = true;
 19893            foreach (var tk in Then.Tokens(args)) yield return tk;
 594            yield return ";";
 595            yield return new NewLineToken();
 596            yield return "} else {";
 597            yield return new NewLineToken();
 598            args.PureRequiresReturn = true;
 10899            foreach (var tk in Else.Tokens(args)) yield return tk;
 5100            yield return ";";
 5101            yield return new NewLineToken();
 5102            yield return "}";
 5103        }
 104        /// <inheritdoc/>
 0105        public override IEnumerable<string> RequiredFunctions() => Then.RequiredFunctions().Concat(Else.RequiredFunction
 106        #region Equality checks
 107        /// <inheritdoc/>
 7108        public override bool Equals(object? obj) => Equals(obj as TernaryExpression);
 109        /// <inheritdoc/>
 7110        public bool Equals(TernaryExpression? other) => !(other is null) && EqualityComparer<PureExpression>.Default.Equ
 111        /// <inheritdoc/>
 0112        public override int GetHashCode() => HashCode.Combine(Condition, Then, Else);
 113        /// <inheritdoc/>
 0114        public static bool operator ==(TernaryExpression? left, TernaryExpression? right) => EqualityComparer<TernaryExp
 115        /// <inheritdoc/>
 0116        public static bool operator !=(TernaryExpression? left, TernaryExpression? right) => !(left == right);
 117        #endregion
 118    }
 119}