Exemple #1
0
        static void TransformProgArgsIfImplementingDeferredReturn([NotNull] ref ZilList bindingList, [NotNull] ref ZilListoidBase body)
        {
            // ends with <LVAL atom>?
            if (!(body.EnumerateNonRecursive().LastOrDefault() is ZilForm lastExpr) || !lastExpr.IsLVAL(out var atom))
            {
                return;
            }

            // atom is bound in the prog?
            if (!GetUninitializedAtomsFromBindingList(bindingList).Contains(atom))
            {
                return;
            }

            // atom is set earlier in the prog?
            var setExpr = body.OfType <ZilForm>()
                          .FirstOrDefault(
                form => form.HasLength(3) &&
                (form.First as ZilAtom)?.StdAtom == StdAtom.SET &&
                form.Rest?.First == atom);

            if (setExpr == null)
            {
                return;
            }

            // atom is not referenced anywhere else?
            if (!body.All(zo =>
                          ReferenceEquals(zo, setExpr) || ReferenceEquals(zo, lastExpr) || !RecursivelyContains(zo, atom)))
            {
                return;
            }

            // we got a winner!
            bindingList = new ZilList(
                bindingList.Where(zo => GetUninitializedAtomFromBindingListItem(zo) != atom));

            body = new ZilList(
                body
                .Where(zo => !ReferenceEquals(zo, lastExpr))
                .Select(zo => ReferenceEquals(zo, setExpr) ? ((IStructure)zo)[2] : zo));
        }