< Summary

Class:NanoCLang.Entities.StructWriteExpression
Assembly:NanoCLang
File(s):C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\Expression\StructWriteExpression.cs
Covered lines:43
Uncovered lines:7
Coverable lines:50
Total lines:103
Line coverage:86% (43 of 50)
Covered branches:18
Total branches:22
Branch coverage:81.8% (18 of 22)

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
get_Structure()100%1100%
get_Member()100%1100%
get_Value()100%1100%
DoInferWorld(...)100%1100%
GetProjectionPointer(...)75%885.71%
FindOffset(...)75%487.5%
Tokens()100%8100%
RequiredFunctions()100%10%
Equals(...)100%1100%
Equals(...)50%2100%
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\StructWriteExpression.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 structure write expressions.
 9    /// </summary>
 10    public class StructWriteExpression : WriteExpression, IEquatable<StructWriteExpression?> {
 11        /// <summary>
 12        /// Creates a new instance of a structure write expression that writes the value to the <paramref name="structur
 13        /// </summary>
 14        /// <param name="structure">Structure to write to.</param>
 15        /// <param name="member">Member in the structure to write to.</param>
 16        /// <param name="value">Value to insert into the <paramref name="member"/>.</param>
 2617        public StructWriteExpression(PureExpression structure, string member, PureExpression value) {
 1318            Structure = structure;
 1319            Member = member;
 1320            Value = value;
 1321        }
 22        /// <summary>
 23        /// Structure that is written to.
 24        /// </summary>
 2125        public PureExpression Structure { get; }
 26        /// <summary>
 27        /// Member in the structure to write to.
 28        /// </summary>
 1329        public string Member { get; }
 30        /// <summary>
 31        /// Value to insert into the <see cref="Member"/>.
 32        /// </summary>
 933        public PureExpression Value { get; }
 34        /// <inheritdoc/>
 935        protected override World DoInferWorld(GlobalEnvironment phi, LocalEnvironment gamma, Heap heap) {
 936            VerbConsole.WriteLine(VerbosityLevel.Default, "T-StrWrite");
 937            return (BaseWrite = new PointerWriteExpression(GetProjectionPointer(phi, gamma, Structure, Member), Value))
 938                .InferWorld(phi, gamma, heap);
 539        }
 40        /// <summary>
 41        /// Resolves the structure projection and outputs a correctly offset pointer to the requested structure member.
 42        /// </summary>
 43        /// <param name="phi">Global environment that contains the structures definition.</param>
 44        /// <param name="gamma">Local environment that contains information about the location of the pointer.</param>
 45        /// <param name="origin">Pointer to the origin of the structure.</param>
 46        /// <param name="member">Name of requested structure member.</param>
 47        /// <returns>Offset pointer to member of structure.</returns>
 1548        internal static PureExpression GetProjectionPointer(GlobalEnvironment phi, LocalEnvironment gamma, PureExpressio
 1549            var type = origin.InferType(gamma);
 1550            var baseType = type.BaseType;
 1551            if (!(baseType is ReferenceType t))
 252                throw new IllFormedException(origin, $"Cannot perform structure projection on non-reference type!");
 1353            if (baseType != new ReferenceType(new Location(t.Location.Name, false), Index.Zero))
 254                throw new IllFormedException(origin, $"Pointer must point to beginning of a structure!");
 1155            if (!gamma.TryGetStructLoc(t.Location.Name, out var structName))
 056                throw new IllFormedException(origin, $"Location {t.Location} is not linked to a structure type!");
 1157            if (!phi.TryGetStruct(structName, out var def))
 058                throw new IllFormedException(origin, $"Link to undefined structure named {structName}!");
 1159            var offset = FindOffset(def, member);
 1060            return origin + new IntegerConstant(offset, 4);
 1061        }
 62
 63        /// <summary>
 64        /// Finds the offset of the requested member in the struct given its definition <paramref name="def"/>.
 65        /// </summary>
 66        /// <param name="def">Structure definition.</param>
 67        /// <param name="member">Requested member to access.</param>
 68        /// <returns>Offset of the member in the struct.</returns>
 1169        private static int FindOffset(StructDefinition def, string member) {
 2670            var memberField = def.Fields.FirstOrDefault(i => i.Name == member);
 1171            if (memberField is null)
 172                throw new IllFormedException(def, $"Structure has no member named {member}!");
 1073            if (!(memberField.Binding.Index is SingletonIndex i))
 074                throw new IllFormedException(def, $"Structure member must point to a signle offset, instead it points to
 1075            return i.Offset;
 1076        }
 77
 78        /// <inheritdoc/>
 479        public override IEnumerable<StringFormatterToken> Tokens(NanoCSourceFormat args) {
 2480            foreach (var tk in Structure.Tokens(args)) yield return tk;
 481            yield return "->";
 482            yield return Member;
 883            if (args.SpaceBeforeBindingAssignment) yield return " ";
 484            yield return "=";
 885            if (args.SpaceAfterBindingAssignment) yield return " ";
 2486            foreach (var tk in Value.Tokens(args)) yield return tk;
 487        }
 88        /// <inheritdoc/>
 089        public override IEnumerable<string> RequiredFunctions() { yield break; }
 90        #region Equality checks
 91        /// <inheritdoc/>
 492        public override bool Equals(object? obj) => Equals(obj as StructWriteExpression);
 93        /// <inheritdoc/>
 494        public bool Equals(StructWriteExpression? other) => !(other is null) && EqualityComparer<PureExpression>.Default
 95        /// <inheritdoc/>
 096        public override int GetHashCode() => HashCode.Combine(Structure);
 97        /// <inheritdoc/>
 098        public static bool operator ==(StructWriteExpression? left, StructWriteExpression? right) => EqualityComparer<St
 99        /// <inheritdoc/>
 0100        public static bool operator !=(StructWriteExpression? left, StructWriteExpression? right) => !(left == right);
 101        #endregion
 102    }
 103}