/// <summary> /// Builds the expression tree from the token queue /// </summary> /// <returns></returns> public Expression BuildTree() { if (_tokenQueue.Count == 0) { Parse(); } // make a copy of the queue, so that we don't empty the original queue Queue <Token> tempQueue = new Queue <Token>(_tokenQueue); Stack <Expression> exprStack = new Stack <Expression>(); List <Expression> args = new List <Expression>(); Stack <String> literalStack = new Stack <String>(); #if DEBUG var q = tempQueue.Select(x => x.Value.ToString() + (x.GetType() == typeof(MemberToken) ? ":" + ((MemberToken)x).Name : "")); System.Diagnostics.Debug.WriteLine(string.Join("][", q.ToArray())); #endif int isCastPending = -1; Type typeCast = null; while (tempQueue.Count > 0) { Token t = tempQueue.Dequeue(); if (isCastPending > -1) { isCastPending--; } if (isCastPending == 0) { exprStack.Push(Expression.Convert(exprStack.Pop(), typeCast)); isCastPending = -1; } if (t.IsIdent) { // handle numeric literals exprStack.Push(Expression.Constant(t.Value, t.Type)); } else if (t.IsType) { exprStack.Push(Expression.Constant(t.Value)); } else if (t.IsOperator) { // handle operators Expression result = null; IOperator op = _operators[(string)t.Value]; Func <OpFuncArgs, Expression> opfunc = OpFuncServiceLocator.Resolve(op.GetType()); for (int i = 0; i < t.ArgCount; i++) { args.Add(exprStack.Pop()); } // Arguments are in reverse order args.Reverse(); result = opfunc(new OpFuncArgs() { TempQueue = tempQueue, ExprStack = exprStack, T = t, Op = op, Args = args }); args.Clear(); exprStack.Push(result); } else if (t.IsCast) { isCastPending = 2; typeCast = t.Type; } } // we should only have one complete expression on the stack, otherwise, something went wrong if (exprStack.Count == 1) { Expression pop = exprStack.Pop(); #if DEBUG System.Diagnostics.Debug.WriteLine(pop.ToString()); #endif return(pop); } else { throw new Exception("Invalid expression"); } return(null); }
/// <summary> /// Builds the expression tree from the token queue /// </summary> /// <returns></returns> public Expression BuildTree(Expression scopeParam, bool isCall) { if (fTokenQueue.Count == 0) { Parse(scopeParam != null); } // make a copy of the queue, so that we don't empty the original queue var tempQueue = new Queue <Token>(fTokenQueue); var exprStack = new Stack <Expression>(); var args = new List <Expression>(); //var literalStack = new Stack<String>(); #if DEBUG var q = tempQueue.Select(x => (x.Value ?? "<null>").ToString() + (x.GetType() == typeof(MemberToken) ? ":" + ((MemberToken)x).Name : "")); System.Diagnostics.Debug.WriteLine(string.Join("][", q.ToArray())); #endif int isCastPending = -1; Type typeCast = null; while (tempQueue.Count > 0) { Token t = tempQueue.Dequeue(); t.IsCall = isCall && tempQueue.Count == 0; if (isCastPending > -1) { isCastPending--; } if (isCastPending == 0) { exprStack.Push(Expression.Convert(exprStack.Pop(), typeCast)); isCastPending = -1; } if (t.IsIdent) { // handle numeric literals exprStack.Push(Expression.Constant(t.Value, t.Type)); } else if (t.IsType) { exprStack.Push(Expression.Constant(t.Value)); } else if (t.IsScope) { if (scopeParam == null) { TkDebug.ThrowToolkitException(string.Format(ObjectUtil.SysCulture, "不是期望的标识符 {0}或者作用域为空", t.Value), this); } exprStack.Push(scopeParam); } else if (t.IsOperator) { // handle operators Expression result = null; var op = fOperators[(string)t.Value]; var opfunc = OpFuncServiceLocator.Resolve(op.GetType()); for (int i = 0; i < t.ArgCount; i++) { args.Add(exprStack.Pop()); } // Arguments are in reverse order args.Reverse(); result = opfunc(new OpFuncArgs() { TempQueue = tempQueue, ExprStack = exprStack, T = t, Op = op, Args = args, ScopeParam = scopeParam, Types = new List <string>() { "System.Linq" } }); args.Clear(); exprStack.Push(result); } else if (t.IsCast) { isCastPending = 2; typeCast = t.Type; } } // we should only have one complete expression on the stack, otherwise, something went wrong if (exprStack.Count == 1) { Expression pop = exprStack.Pop(); #if DEBUG System.Diagnostics.Debug.WriteLine(pop.ToString()); #endif return(pop); } else { TkDebug.ThrowToolkitException("非法的表达式", this); return(null); } }