private static Expression ReadFunction(XmlExpressionReader reader)
        {
            ParameterExpression[] variables = null;
            Expression            body      = null;

            string name       = reader.ReadAttributeValue("name", null);
            Type   returnType = reader.ReadAttributeValue <Type>("returnType", typeof(void));

            if (!string.IsNullOrEmpty(name))
            {
                reader.Context.AddVariable(returnType, name);
            }

            var exprs = reader.ReadChildExpressions(out variables);

            if (exprs == null || exprs.Length == 0)
            {
                throw new NotBodyNodeException(reader.Node);
            }
            if (exprs != null && exprs.Length > 0)
            {
                body = exprs[0];
            }

            return(Function(name, variables, body, returnType));
        }
        private static TypeBinaryExpresion ReadTypeIs(XmlExpressionReader reader)
        {
            var  childs        = reader.ReadChildExpressions(0, 2);
            Type convertToType = childs[1].ValueType;

            return(TypeIs(childs[0], convertToType));
        }
        private static ConditionalExpression ReadIf(XmlExpressionReader reader, Expression ifFalse)
        {
            var        childs = reader.ReadChildExpressions(0, 2);
            Expression test, ifTrue;

            if (childs == null || childs.Length == 0)
            {
                throw new MissingNodeException(Resource1.Read_NotTestValueNode, reader.Node, null);
            }
            if (childs.Length == 1)
            {
                throw new ExpressionReadException(Resource1.Read_NotBodyNode, reader.Node);
            }
            test   = childs[0];
            ifTrue = childs[1];

            var elseIfNodes = reader.Node.SelectNodes("x:elseIf", reader.nsmgr);

            for (int i = elseIfNodes.Count - 1; i >= 0; i--)
            {
                var child = elseIfNodes[i];
                reader.ReadStartExpression(child);
                ifFalse = ReadIf(reader, ifFalse);
                reader.ReadEndExpression();
            }

            if (childs.Length == 1)
            {
                return(If(test, null, ifFalse));
            }

            return(If(test, ifTrue, ifFalse));
        }
        private static Expression ReadBlock(XmlExpressionReader reader)
        {
            ParameterExpression[] vars = null;
            reader.PushScope();
            var exprs = reader.ReadChildExpressions(out vars);

            reader.PopScope();
            return(Block(vars, exprs));
        }
        private static Expression ReadReturn(XmlExpressionReader reader)
        {
            var exprs = reader.ReadChildExpressions();

            if (exprs == null && exprs.Length == 0)
            {
                return(Return());
            }

            return(Return(exprs[0]));
        }
        private static Expression ReadProperty(XmlExpressionReader reader)
        {
            string     propertyName = reader.ReadAttributeValue("name");
            Type       type         = reader.ReadAttributeValue <Type>("type", null);
            Expression instance;
            var        exprs = reader.ReadChildExpressions();

            if (exprs == null || exprs.Length == 0)
            {
                throw new MissingNodeException(Resource1.Read_NotInstanceOrTypeNode, reader.Node, null);
            }
            instance = exprs[0];
            //if (exprs[0] is ConstantExpression)
            //    type = ((ConstantExpression)exprs[0]).Value as Type;
            //if (type == null)
            //{
            //    return Property(exprs[0], propertyName);
            //}
            return(Property(instance, type ?? instance.ValueType, propertyName));
        }
        private static Expression ReadMethodCall(XmlExpressionReader reader)
        {
            string     methodName = reader.ReadAttributeValue("method", null);
            Expression callExpr;

            reader.PushScope();

            var exprs = reader.ReadChildExpressions();

            if (exprs == null || exprs.Length == 0)
            {
                throw new MissingNodeException(reader.Node, null);
            }

            if (string.IsNullOrEmpty(methodName))
            {
                Type returnType = exprs[0].ValueType;
                //function
                callExpr = Call(exprs[0], returnType, exprs.Skip(1));
            }
            else
            {
                Type       type     = reader.ReadAttributeValue <Type>("type", null);
                Type[]     argTypes = ReadTypes(reader.ReadAttributeValue("argTypes", null));
                Expression instance = exprs[0];
                //if (instance == Null)
                //    instance = null;
                //if (instance != null)
                //{
                callExpr = Call(instance, type ?? instance.ValueType, methodName, argTypes, exprs.Skip(1));
                //}
                //else
                //{
                //    callExpr = Call(type, methodName, argTypes, exprs.Skip(1));
                //}
            }

            reader.PopScope();
            return(callExpr);
        }
        private static Expression ReadLoop(XmlExpressionReader reader)
        {
            var exprs = reader.ReadChildExpressions(0, 2);

            if (exprs.Length == 0)
            {
                throw new NotBodyNodeException(reader.Node);
            }

            Expression test, body, loop;

            test = exprs[0];
            if (exprs.Length == 2)
            {
                body = exprs[1];
                loop = Loop(Block(If(Not(test), Break()), body));
            }
            else
            {
                loop = Loop(Block(If(Not(test), Break())));
            }
            return(loop);
        }
        private static Expression ReadSwitch(XmlExpressionReader reader)
        {
            var childs = reader.FilterChildNodeTypes();
            var first  = childs.FirstOrDefault();

            if (first == null)
            {
                throw new MissingNodeException(Resource1.Read_NotTestValueNode, reader.Node, null);
            }
            Expression testValue;

            Expression defaultBody = null;

            reader.ReadStartExpression(first);
            testValue = reader.ReadExpression();
            reader.ReadEndExpression();

            List <SwitchCase> cases = new List <SwitchCase>();

            foreach (XmlNode child in childs.Skip(1))
            {
                if (child.LocalName == "case")
                {
                    reader.ReadStartExpression(child);
                    var exprs = reader.ReadChildExpressions();

                    if (exprs == null || exprs.Length == 0)
                    {
                        throw new MissingNodeException(Resource1.Read_NotTestValueNode, child, null);
                    }
                    if (exprs.Length < 2)
                    {
                        throw new NotBodyNodeException(child);
                    }

                    var        testValues = exprs.Take(exprs.Length - 1);
                    var        body       = exprs.Last();
                    SwitchCase sc         = new SwitchCase(testValues, body);
                    cases.Add(sc);

                    reader.ReadEndExpression();
                }
                else if (child.LocalName == "default")
                {
                    reader.ReadStartExpression(child);
                    var exprs = reader.ReadChildExpressions();
                    if (exprs == null || exprs.Length == 0)
                    {
                        throw new NotBodyNodeException(child);
                    }
                    if (defaultBody != null)
                    {
                        throw new DuplicateNodeException(child);
                    }
                    defaultBody = exprs.First();
                    reader.ReadEndExpression();
                }
            }

            return(Switch(testValue, defaultBody, cases));
        }