Inheritance: CodeObject
 ScriptObject ParseOperate(CodeOperator operate)
 {
     TokenType type = operate.Operator;
     ScriptObject left = ResolveOperand(operate.Left);
     switch (type) {
     case TokenType.Plus:
         ScriptObject right = ResolveOperand(operate.Right);
         if (left is ScriptString || right is ScriptString) {
             return new ScriptString(m_script, left.ToString() + right.ToString());
         }
         return left.Compute(type, right);
     case TokenType.Minus:
     case TokenType.Multiply:
     case TokenType.Divide:
     case TokenType.Modulo:
     case TokenType.InclusiveOr:
     case TokenType.Combine:
     case TokenType.XOR:
     case TokenType.Shr:
     case TokenType.Shi:
         return left.Compute(type, ResolveOperand(operate.Right));
     case TokenType.And:
         if (!left.LogicOperation()) return m_script.False;
         return m_script.CreateBool(ResolveOperand(operate.Right).LogicOperation());
     case TokenType.Or:
         if (left.LogicOperation()) return m_script.True;
         return m_script.CreateBool(ResolveOperand(operate.Right).LogicOperation());
     case TokenType.Equal:
         return m_script.CreateBool(left.Equals(ResolveOperand(operate.Right)));
     case TokenType.NotEqual:
         return m_script.CreateBool(!left.Equals(ResolveOperand(operate.Right)));
     case TokenType.Greater:
     case TokenType.GreaterOrEqual:
     case TokenType.Less:
     case TokenType.LessOrEqual:
         return m_script.CreateBool(left.Compare(type, ResolveOperand(operate.Right)));
     default:
         throw new ExecutionException(m_script, "不支持的运算符 " + type);
     }
 }
 //获取一个Object
 private CodeObject GetObject()
 {
     Stack<TempOperator> operateStack = new Stack<TempOperator>();
     Stack<CodeObject> objectStack = new Stack<CodeObject>();
     while (true) {
         objectStack.Push(GetOneObject());
         if (!P_Operator(operateStack, objectStack))
             break;
     }
     while (true) {
         if (operateStack.Count <= 0)
             break;
         TempOperator oper = operateStack.Pop();
         CodeOperator binexp = new CodeOperator(objectStack.Pop(), objectStack.Pop(), oper.Operator, m_strBreviary, GetSourceLine());
         objectStack.Push(binexp);
     }
     CodeObject ret = objectStack.Pop();
     if (ret is CodeMember) {
         CodeMember member = ret as CodeMember;
         if (member.Calc == CALC.NONE) {
             Token token = ReadToken();
             switch (token.Type) {
                 case TokenType.Assign:
                 case TokenType.AssignPlus:
                 case TokenType.AssignMinus:
                 case TokenType.AssignMultiply:
                 case TokenType.AssignDivide:
                 case TokenType.AssignModulo:
                 case TokenType.AssignCombine:
                 case TokenType.AssignInclusiveOr:
                 case TokenType.AssignXOR:
                 case TokenType.AssignShr:
                 case TokenType.AssignShi:
                     ret = new CodeAssign(member, GetObject(), token.Type, m_strBreviary, token.SourceLine);
                     break;
                 default:
                     UndoToken();
                     break;
             }
         }
     }
     if (PeekToken ().Type == TokenType.QuestionMark) {
         ReadToken();
         CodeTernary ternary = new CodeTernary();
         ternary.Allow = ret;
         ternary.True = GetObject();
         ReadColon();
         ternary.False = GetObject();
         return ternary;
     }
     return ret;
 }
 //解析操作符
 private bool P_Operator(Stack<TempOperator> operateStack, Stack<CodeObject> objectStack)
 {
     TempOperator curr = TempOperator.GetOper(PeekToken().Type);
     if (curr == null) return false;
     ReadToken();
     while (operateStack.Count > 0) {
         TempOperator oper = operateStack.Peek();
         if (oper.Level >= curr.Level) {
             operateStack.Pop();
             CodeOperator binexp = new CodeOperator(objectStack.Pop(), objectStack.Pop(), oper.Operator, m_strBreviary, GetSourceLine());
             objectStack.Push(binexp);
         } else {
             break;
         }
     }
     operateStack.Push(curr);
     return true;
 }
 ScriptObject ParseOperate(CodeOperator operate)
 {
     TokenType type = operate.Operator;
     ScriptObject left = ResolveOperand(operate.Left);
     if (type == TokenType.Plus) {
         ScriptObject right = ResolveOperand(operate.Right);
         if (left is ScriptString || right is ScriptString) {
             return m_script.CreateString(left.ToString() + right.ToString());
         } else if (left is ScriptNumber && right is ScriptNumber){
             return (left as ScriptNumber).Compute(TokenType.Plus, right as ScriptNumber);
         } else {
             throw new ExecutionException(m_script, "operate [+] left right is not same type");
         }
     } else if (type == TokenType.Minus || type == TokenType.Multiply || type == TokenType.Divide || type == TokenType.Modulo ||
         type == TokenType.InclusiveOr || type == TokenType.Combine || type == TokenType.XOR || type == TokenType.Shr || type == TokenType.Shi) {
         ScriptNumber leftNumber = left as ScriptNumber;
         if (leftNumber == null) throw new ExecutionException(m_script, "运算符[左边]必须是number类型");
         ScriptNumber rightNumber = ResolveOperand(operate.Right) as ScriptNumber;
         if (rightNumber == null) throw new ExecutionException(m_script, "运算符[右边]必须是number类型");
         return leftNumber.Compute(type, rightNumber);
     } else {
         if (left is ScriptBoolean) {
             bool b1 = ((ScriptBoolean)left).Value;
             if (type == TokenType.And) {
                 if (b1 == false) return m_script.False;
                 ScriptBoolean right = ResolveOperand(operate.Right) as ScriptBoolean;
                 if (right == null) throw new ExecutionException(m_script, "operate [&&] right is not a bool");
                 return right.Value ? m_script.True : m_script.False;
             } else if (type == TokenType.Or) {
                 if (b1 == true) return m_script.True;
                 ScriptBoolean right = ResolveOperand(operate.Right) as ScriptBoolean;
                 if (right == null) throw new ExecutionException(m_script, "operate [||] right is not a bool");
                 return right.Value ? m_script.True : m_script.False;
             } else {
                 if (type != TokenType.Equal && type != TokenType.NotEqual)
                     throw new ExecutionException(m_script, "nonsupport operate [" + type + "]  with bool");
                 ScriptBoolean right = ResolveOperand(operate.Right) as ScriptBoolean;
                 if (right == null) return type == TokenType.Equal ? m_script.False : m_script.True;
                 bool b2 = right.Value;
                 if (type == TokenType.Equal)
                     return b1 == b2 ? m_script.True : m_script.False;
                 else
                     return b1 != b2 ? m_script.True : m_script.False;
             }
         } else {
             ScriptObject right = ResolveOperand(operate.Right);
             if (left is ScriptNull || right is ScriptNull) {
                 bool ret = false;
                 if (type == TokenType.Equal)
                     ret = (left == right);
                 else if (type == TokenType.NotEqual)
                     ret = (left != right);
                 else
                     throw new ExecutionException(m_script, "nonsupport operate [" + type + "] with null");
                 return ret ? m_script.True : m_script.False;
             }
             if (type == TokenType.Equal) {
                 return left.ObjectValue.Equals(right.ObjectValue) ? m_script.True : m_script.False;
             } else if (type == TokenType.NotEqual) {
                 return !left.ObjectValue.Equals(right.ObjectValue) ? m_script.True : m_script.False;
             }
             if (left.Type != right.Type)
                 throw new ExecutionException(m_script, "[operate] left right is not same type");
             if (left is ScriptString) {
                 return ((ScriptString)left).Compare(type, (ScriptString)right) ? m_script.True : m_script.False;
             } else if (left is ScriptNumber) {
                 return ((ScriptNumber)left).Compare(type, (ScriptNumber)right) ? m_script.True : m_script.False;
             } else {
                 throw new ExecutionException(m_script, "nonsupport operate [" + type + "] with " + left.Type);
             }
         }
     }
 }