private static IEnumerable <ITypedElement> runRepeat(Closure ctx, IEnumerable <Invokee> arguments)
        {
            var focus  = arguments.First()(ctx, InvokeeFactory.EmptyArgs);
            var lambda = arguments.Skip(1).First();

            var fullResult = new List <ITypedElement>();
            List <ITypedElement> newNodes = new List <ITypedElement>(focus);

            while (newNodes.Any())
            {
                var current = newNodes;
                newNodes = new List <ITypedElement>();

                foreach (ITypedElement element in current)
                {
                    var newFocus   = ElementNode.CreateList(element);
                    var newContext = ctx.Nest(newFocus);
                    newContext.SetThis(newFocus);


                    newNodes.AddRange(lambda(newContext, InvokeeFactory.EmptyArgs));
                }

                fullResult.AddRange(newNodes);
            }

            return(fullResult);
        }
예제 #2
0
        private static IEnumerable <ITypedElement> runAny(Closure ctx, IEnumerable <Invokee> arguments)
        {
            var focus  = arguments.First()(ctx, InvokeeFactory.EmptyArgs);
            var lambda = arguments.Skip(1).First();
            var index  = 0;

            foreach (ITypedElement element in focus)
            {
                var newFocus   = ElementNode.CreateList(element);
                var newContext = ctx.Nest(newFocus);
                newContext.SetThis(newFocus);
                newContext.SetIndex(ElementNode.CreateList(index));
                index++;

                var result = lambda(newContext, InvokeeFactory.EmptyArgs).BooleanEval();

                //if (result == null) return ElementNode.EmptyList; -> otherwise this would not be where().exists()
                //Patient.identifier.any(use = 'official') would return {} if ANY identifier has no 'use' element. Unexpected behaviour, I think
                if (result == true)
                {
                    return(ElementNode.CreateList(true));
                }
            }

            return(ElementNode.CreateList(false));
        }
예제 #3
0
        private static IEnumerable <ITypedElement> runAll(Closure ctx, IEnumerable <Invokee> arguments)
        {
            var focus  = arguments.First()(ctx, InvokeeFactory.EmptyArgs);
            var lambda = arguments.Skip(1).First();
            var index  = 0;

            foreach (ITypedElement element in focus)
            {
                var newFocus   = ElementNode.CreateList(element);
                var newContext = ctx.Nest(newFocus);
                newContext.SetThis(newFocus);
                newContext.SetIndex(ElementNode.CreateList(index));
                index++;

                var result = lambda(newContext, InvokeeFactory.EmptyArgs).BooleanEval();
                if (result == null)
                {
                    return(ElementNode.EmptyList);
                }
                if (result == false)
                {
                    return(ElementNode.CreateList(false));
                }
            }

            return(ElementNode.CreateList(true));
        }
예제 #4
0
        public static Closure Nest(this Closure ctx, IEnumerable <ITypedElement> input)
        {
            var nested = ctx.Nest();

            nested.SetThat(input);

            return(nested);
        }
        private static IEnumerable <ITypedElement> runWhere(Closure ctx, IEnumerable <Invokee> arguments)
        {
            var focus  = arguments.First()(ctx, InvokeeFactory.EmptyArgs);
            var lambda = arguments.Skip(1).First();

            foreach (ITypedElement element in focus)
            {
                var newFocus   = ElementNode.CreateList(element);
                var newContext = ctx.Nest(newFocus);
                newContext.SetThis(newFocus);

                if (lambda(newContext, InvokeeFactory.EmptyArgs).BooleanEval() == true)
                {
                    yield return(element);
                }
            }
        }
        private static IEnumerable <ITypedElement> runSelect(Closure ctx, IEnumerable <Invokee> arguments)
        {
            var focus  = arguments.First()(ctx, InvokeeFactory.EmptyArgs);
            var lambda = arguments.Skip(1).First();

            foreach (ITypedElement element in focus)
            {
                var newFocus   = ElementNode.CreateList(element);
                var newContext = ctx.Nest(newFocus);
                newContext.SetThis(newFocus);

                var result = lambda(newContext, InvokeeFactory.EmptyArgs);
                foreach (var resultElement in result)       // implement SelectMany()
                {
                    yield return(resultElement);
                }
            }
        }
예제 #7
0
        public IEnumerable <ITypedElement> Dispatcher(Closure context, IEnumerable <Invokee> args)
        {
            var actualArgs = new List <IEnumerable <ITypedElement> >();

            var focus = args.First()(context, InvokeeFactory.EmptyArgs);

            if (!focus.Any())
            {
                return(ElementNode.EmptyList);
            }

            actualArgs.Add(focus);
            var newCtx = context.Nest(focus);

            actualArgs.AddRange(args.Skip(1).Select(a => a(newCtx, InvokeeFactory.EmptyArgs)));
            if (actualArgs.Any(aa => !aa.Any()))
            {
                return(ElementNode.EmptyList);
            }

            var entry = _scope.DynamicGet(_name, actualArgs);

            if (entry != null)
            {
                try
                {
                    // The Get() here should never fail, since we already know there's a (dynamic) matching candidate
                    // Need to clean up this duplicate logic later

                    var argFuncs = actualArgs.Select(arg => InvokeeFactory.Return(arg));
                    return(entry(context, argFuncs));
                }
                catch (TargetInvocationException tie)
                {
                    // Unwrap the very non-informative T.I.E, and throw the nested exception instead
                    throw tie.InnerException;
                }
            }
            else
            {
                //TODO: Make error reporting better
                throw Error.Argument(noMatchError(actualArgs));
            }
        }
예제 #8
0
        private static IEnumerable <IElementNavigator> runAll(Closure ctx, IEnumerable <Invokee> arguments)
        {
            var focus  = arguments.First()(ctx, InvokeeFactory.EmptyArgs);
            var lambda = arguments.Skip(1).First();

            foreach (IElementNavigator element in focus)
            {
                var newFocus   = FhirValueList.Create(element);
                var newContext = ctx.Nest(newFocus);
                newContext.SetThis(newFocus);

                var result = lambda(newContext, InvokeeFactory.EmptyArgs).BooleanEval();
                if (result == null)
                {
                    return(FhirValueList.Empty);
                }
                if (result == false)
                {
                    return(FhirValueList.Create(false));
                }
            }

            return(FhirValueList.Create(true));
        }