< Summary

Class:NanoCLang.Entities.UnfoldExpression
Assembly:NanoCLang
File(s):C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\Expression\UnfoldExpression.cs
Covered lines:93
Uncovered lines:10
Coverable lines:103
Total lines:149
Line coverage:90.2% (93 of 103)
Covered branches:51
Total branches:70
Branch coverage:72.8% (51 of 70)

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
get_Name()100%1100%
get_Location()100%1100%
get_Expression()100%1100%
get_Next()100%1100%
DoInferWorld(...)71.42%2883.33%
Tokens()77.77%18100%
Tokens()80%20100%
RequiredFunctions()100%1100%
Equals(...)100%1100%
Equals(...)50%8100%
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\UnfoldExpression.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 unfold expressions.
 9    /// </summary>
 10    public class UnfoldExpression : Expression, IEquatable<UnfoldExpression?> {
 11        /// <summary>
 12        /// Creates an instance of an unfold expression that unfolds the pointer in the <paramref name="expression"/> at
 13        /// </summary>
 14        /// <param name="name">Name of the binding.</param>
 15        /// <param name="location">Location that the <paramref name="expression"/> refers to.</param>
 16        /// <param name="expression">Expression that is bound to the <paramref name="name"/>.</param>
 17        /// <param name="next">Expression that is evaluated with the binding.</param>
 3018        public UnfoldExpression(string name, string location, PureExpression expression, Expression next) {
 1519            Name = name;
 1520            Location = location;
 1521            Expression = expression;
 1522            Next = next;
 1523        }
 24        /// <summary>
 25        /// Name that the <see cref="Expression"/> is bound to.
 26        /// </summary>
 3527        public string Name { get; }
 28        /// <summary>
 29        /// Location that the pointer in the <see cref="Expression"/> refers to.
 30        /// </summary>
 3531        public string Location { get; }
 32        /// <summary>
 33        /// Pointer that shall be unfolded and bound to the <see cref="Name"/>.
 34        /// </summary>
 4135        public PureExpression Expression { get; }
 36        /// <summary>
 37        /// Expression that is evaluated with the binding.
 38        /// </summary>
 4139        public Expression Next { get; }
 40        /// <inheritdoc/>
 641        protected override World DoInferWorld(GlobalEnvironment phi, LocalEnvironment gamma, Heap heap) {
 642            var ptrType = Expression.InferType(gamma);
 643            if (!(ptrType.BaseType is ReferenceType ptrBase))
 044                throw new IllFormedException(Expression, $"Cannot unfold expression of non-reference type {ptrType.BaseT
 645            var labs = ptrBase.Location;
 646            var lj = new Location(labs.Name, false);
 647            if (ptrBase.Concrete)
 048                throw new IllFormedException(Expression, $"Cannot unfold reference to concrete location {labs}!");
 649            if (!heap.TryGetBinding(labs, out var b))
 050                throw new IllFormedException(Expression, $"Cannot unfold reference to location {labs} without a heap bin
 651            if (heap.Contains(lj))
 052                throw new IllFormedException(Expression, $"Cannot unfold, because {lj} was already unfolded in heap!");
 1253            if (!ptrType.SubType(gamma, new RefinedType(ptrBase, v => PureExpression.UnqualExpression(v, new IntegerCons
 054                throw new IllFormedException(Expression, $"Cannot unfold possibly nullptr reference {ptrBase}!");
 655            var theta = new Substitutor();
 3956            for (var i = 0; i < b.Length; i++) {
 957                var blockType = b[i];
 958                switch (blockType.Index) {
 59                case SingletonIndex idx:
 660                    var fresh = new VariableExpression(Heap.OffsetVar(idx.Offset));
 661                    theta.BlockOffsets.Add(idx.Offset, fresh);
 662                    break;
 363                case SequenceIndex idx: break;
 064                default: throw new InvalidProgramException("Expected singleton or sequence index!");
 65                }
 966            }
 667            BlockType[] bj = new BlockType[b.Length];
 3968            for (var i = 0; i < b.Length; i++) {
 969                var blockType = b[i];
 70                bj[i] = (blockType.Index) switch {
 1271                    SingletonIndex idx => new BlockType((Index)idx.Clone(), new RefinedType(blockType.Type.BaseType, v =
 372                    SequenceIndex idx => new BlockType((Index)idx.Clone(), blockType.Type.Replace(theta)),
 073                    _ => throw new InvalidProgramException("Expected singleton or sequence index!")
 74                };
 975            }
 676            var h1 = heap * new Heap(new LocationBinding(lj, bj));
 2477            var world = gamma.With(b.Where(i => i.Index is SingletonIndex)
 1278                .Select(i => new KeyValuePair<string, Type>(Heap.OffsetVar((i.Index as SingletonIndex ?? throw new Inval
 679                gamma => {
 680                    h1.WellFormed(gamma);
 1281                    return gamma.With(Name, new RefinedType(new ReferenceType(lj, ptrBase.Offsets), v => PureExpression.
 1282                        gamma => Next.InferWorld(phi, gamma, h1));
 1283                });
 684            world.WellFormed(gamma);
 685            return world;
 686        }
 87        /// <inheritdoc/>
 788        public override IEnumerable<StringFormatterToken> Tokens(NanoCSourceFormat args) {
 789            yield return "letu";
 790            yield return " ";
 791            yield return Name;
 1492            if (args.SpaceBeforeBindingAssignment) yield return " ";
 793            yield return "=";
 1494            if (args.SpaceAfterBindingAssignment) yield return " ";
 795            yield return "[";
 796            if (args.SpaceBeforeFoldingKeywords) yield return " ";
 797            yield return "unfold";
 798            yield return " ";
 799            yield return Location;
 7100            if (args.SpaceAfterFoldingKeywords) yield return " ";
 7101            yield return "]";
 7102            if (args.SpaceBetweenUnfoldAndExpression) yield return " ";
 42103            foreach (var tk in Expression.Tokens(args)) yield return tk;
 7104            yield return " ";
 7105            yield return "in";
 7106            if (args.NewlinesAfterUnfoldExpression <= 0) yield return " ";
 35107            else for (int i = 0; i < args.NewlinesAfterUnfoldExpression; i++) yield return new NewLineToken();
 1596108            foreach (var tk in Next.Tokens(args)) yield return tk;
 7109        }
 110        /// <inheritdoc/>
 6111        public override IEnumerable<StringFormatterToken> Tokens(CSourceFormat args) {
 54112            foreach (var tk in new ReferenceType(new Location(Location, true), Index.Zero).Tokens(args)) yield return tk
 6113            yield return " ";
 6114            yield return Name;
 12115            if (args.SpaceBeforeBindingAssignment) yield return " ";
 6116            yield return "=";
 12117            if (args.SpaceAfterBindingAssignment) yield return " ";
 6118            yield return "/* [";
 6119            if (args.SpaceBeforeFoldingKeywords) yield return " ";
 6120            yield return "unfold";
 6121            yield return " ";
 6122            yield return Location;
 6123            if (args.SpaceAfterFoldingKeywords) yield return " ";
 6124            yield return "] */ ";
 6125            args.PureRequiresReturn = false;
 6126            if (args.SpaceBetweenUnfoldAndExpression) yield return " ";
 36127            foreach (var tk in Expression.Tokens(args)) yield return tk;
 6128            yield return ";";
 6129            if (args.NewlinesAfterUnfoldExpression <= 0) yield return " ";
 30130            else for (int i = 0; i < args.NewlinesAfterUnfoldExpression; i++) yield return new NewLineToken();
 6131            args.PureRequiresReturn = false;
 2196132            foreach (var tk in Next.Tokens(args)) yield return tk;
 6133        }
 134        /// <inheritdoc/>
 6135        public override IEnumerable<string> RequiredFunctions() => Next.RequiredFunctions();
 136        #region Equality checks
 137        /// <inheritdoc/>
 8138        public override bool Equals(object? obj) => Equals(obj as UnfoldExpression);
 139        /// <inheritdoc/>
 8140        public bool Equals(UnfoldExpression? other) => !(other is null) && Name == other.Name && Location == other.Locat
 141        /// <inheritdoc/>
 0142        public override int GetHashCode() => HashCode.Combine(Name, Location, Expression, Next);
 143        /// <inheritdoc/>
 0144        public static bool operator ==(UnfoldExpression? left, UnfoldExpression? right) => EqualityComparer<UnfoldExpres
 145        /// <inheritdoc/>
 0146        public static bool operator !=(UnfoldExpression? left, UnfoldExpression? right) => !(left == right);
 147        #endregion
 148    }
 149}