private Expression BuildFunctorInvokeExpression(AtomMetadata atom, Expression[] args)
 {
     return atom.MethodTarget == null
             ? Expression.Call(atom.MethodInfo, args)
             : Expression.Call(Expression.Constant(atom.MethodTarget), atom.MethodInfo, args);
 }
        private Expression BuildFunctorInvokeExpression(AtomMetadata atom, Expression adjustedContext)
        {
            if (adjustedContext == null)
            {
                return atom.MethodTarget == null
                        ? Expression.Call(atom.MethodInfo)
                        : Expression.Call(Expression.Constant(atom.MethodTarget), atom.MethodInfo);
            }

            return atom.MethodTarget == null
                    ? Expression.Call(atom.MethodInfo, adjustedContext)
                    : Expression.Call(Expression.Constant(atom.MethodTarget), atom.MethodInfo, adjustedContext);
        }
        private Expression BuildFunCallExpressionFromMethodInfo(AtomMetadata atom, ParseTreeNode root, CompilerState state)
        {
            // number of arguments must exactly match number of child nodes in the tree
            var paramInfo = atom.MethodInfo.GetParameters();

            var funArgs = root.RequireChild("exprList", 1, 0);
            funArgs.RequireChildren(paramInfo.Length);

            // types and order of arguments must match nodes in the tree
            var args = new Expression[paramInfo.Length];

            for (var i = 0; i < paramInfo.Length; i++)
            {
                var param = paramInfo[i];
                var argNode = funArgs.ChildNodes[i];
                var value = state.ParentRuntime.Analyze(argNode, state);

                Expression adjusted;
                if (!ExpressionTreeExtensions.TryAdjustReturnType(root, value, param.ParameterType, out adjusted))
                {
                    throw new CompilationException(string.Format("Could not adjust parameter number {0} to invoke function {1}",
                        i, atom.Name), funArgs.ChildNodes[i]);
                }

                args[i] = adjusted;
            }

            return BuildFunctorInvokeExpression(atom, args);
        }