@Override public void eval(final ExecutionContext context) { /* * Eval left */ context.newCallStackFrame(LEFT_POS); left.eval(context); context.returnFromCallFrame(); /* * If it is a function pointer, then create a new function call */ final Object target = left.getAnnotation(); if (isApply && target instanceof FunctionDefinition) { final FunctionDefinition fd = (FunctionDefinition) target; /* * Currently, there is no change in the codepath when superscript is * executed: f.apply(...) is exactly equivalent to f(...). */ final FunctionCall fc; final boolean hasCall = getSuperscript() instanceof FunctionCall; final FunctionCall prevFC = hasCall ? (FunctionCall) getSuperscript() : null; if (hasCall && fd.equals(prevFC.getFunctionDefinition())) { fc = prevFC; } else { fc = new FunctionCall(fd, deepCopyBranches()); } setSuperscript(fc); fc.eval(context); setAnnotation(fc.getAnnotation()); } else { /* * Otherwise, evaluate branches and proceed to evaluation */ projectAndEval(context); /* * Check everything for fields */ final Stream<?> argsstr = getBranchesAnnotationStream(); final Object[] args = argsstr.toArray(); /* * collect any field indices */ List<Integer> list = new ArrayList<>(); for (Object o : args) { if (Field.class.isAssignableFrom(o.getClass())) { list.add(ArrayUtils.indexOf(args, o)); } } final int[] fieldIndexes = new int[list.size()]; for (Integer i : list) { fieldIndexes[i] = list.get(i); } // End /* * if there are any fields, do a field apply: */ final boolean fieldTarget = target instanceof Field; if (fieldTarget || fieldIndexes.length > 0) { /* * Run on every element of the field, and at each iteration use the * current annotation as corresponding element for the field. Once * done, set the entire field as annotation. */ final Field res = Fields.apply( new BiFunction<Object, Object[], Object>() { @Override public Object apply(Object actualT, Object[] actualA) { return ReflectionUtils.invokeBestNotStatic(actualT, methodName, actualA); } }, fieldTarget, fieldIndexes, target, args); setAnnotation(res); } else { final Object annotation = ReflectionUtils.invokeBestNotStatic(target, methodName, args); setAnnotation(annotation); } } }