/// <summary>
 ///     加法
 /// </summary>
 public static ScriptObject Add(ScriptObject obj1,ScriptObject obj2)
 {
     if (obj1.Type != obj2.Type)
     {
         return GetNil();
     }
     if (obj1.Type == ValueType.NUMBER)
     {
         ScriptObject s = ScriptObject.CreateNum(obj1.Value.Number + obj2.Value.Number);
         return s;
     }
     return GetNil();
 }
 public static void SetThisValue(ScriptObject own)
 {
     StackState stack = RunEnvironment.Instance.LocalStack;
     Instructor.AssignVar(stack.This, own);
 }
        /// <summary>
        ///    将函数压栈,准备调用
        /// </summary>
        /// <param name="func"></param>
        internal void PushFunction(ScriptObject func)
        {
            Contract.Assert(func !=null && func.Type == ValueType.FUNCTION);

            stack.Add(func);

            _funcPushStack.Push(stack.Count - 1);  //指向函数
        }
 internal int Push(ScriptObject obj)
 {
     ScriptObject o = ScriptObject.CreateScriptObject(obj);
     stack.Add(o);
     return Top - 1;
 }
 internal void AddInArray(ScriptObject obj)
 {
     AddFileld(count,obj);
 }
        /// <summary>
        ///    先这样处理吧,没有找到算法的具体实现
        /// </summary>
        public void AddFileld(int index,ScriptObject value)
        {
            int newsize;

            if (index < 0)
            {
                AddFileld(index.ToString(), value);
            }
            else if (index < _array.Length)
            {
                _array[index] = value;
                ++count;
            }
            else if ((newsize = (count + 1) * 2) >= index)
            {
                Array.Resize(ref _array, newsize);
                _array[index] = value;
                ++count;
            }
            else
            {
                AddFileld(index.ToString(), value);
            }
        }
        internal void RemoveFileld(ScriptObject index)
        {
            Contract.Assert(Type == ValueType.TABLE);

            switch (index.Type)
            {
                case ValueType.NUMBER:

                    int at = (int)index.Value.Number;

                    Value.RefPartHandle.ConverToTablePart().Remove(at);

                    break;

                case ValueType.STRING:

                    string key = index.Value.RefPartHandle.ConverToStringPart().Value;

                    Value.RefPartHandle.ConverToTablePart().Remove(key);

                    break;

                default:
                    Contract.Assert(false);
                    break;
            }
        }
        internal ScriptObject GetFileld(ScriptObject index)
        {
            Contract.Assert(Type == ValueType.TABLE);

            ScriptObject s = null;

            switch (index.Type)
            {
                case ValueType.NUMBER:

                    s = Value.RefPartHandle.ConverToTablePart().IndexAt((int)index.Value.Number);

                    break;

                case ValueType.STRING:

                    s = Value.RefPartHandle.ConverToTablePart().TryGetValue(index.Value.RefPartHandle.ConverToStringPart().Value);

                    break;

                default:
                    Contract.Assert(false);
                    break;
            }
            if (s == null) return RunEnvironment.Nil;

            return s;
        }
 public static void ClearTableItem(ScriptObject own, ScriptObject index)
 {
     own.RemoveFileld(index);
 }
 /// <summary>
 ///    将表中某字段清掉
 /// </summary>
 public static void ClearTableFileld(ScriptObject  own,string name)
 {
     own.RemoveFileld(name);
 }
 public static ScriptObject TableAddInArray(ScriptObject table,ScriptObject value)
 {
     table.AddInArray(value);
     return table;
 }
 public static ScriptObject TableAddFileld(ScriptObject table,string name,ScriptObject value)
 {
     table.AddFileld(name,value);
     return table;
 }
 /// <summary>
 ///    将局部变量压栈
 /// </summary>
 /// <param name="obj"></param>
 public static void StackPush(ScriptObject obj)
 {
     StackState stack = RunEnvironment.Instance.LocalStack;
     stack.Push(obj);
 }
        /// <summary>
        ///    设置Upvalues的长度
        /// </summary>
        public static void SetUpvaluesLength(ScriptObject function,int length)
        {
            Contract.Assert(function.Type == ValueType.FUNCTION);

            FuncPart func =  function.Value.RefPartHandle.ConverToFuncPart();

            func.UpVals = new ScriptObject[length];
        }
        /// <summary>
        ///   设置每一个UpValue
        /// </summary>
        public static void SetUpvalue(ScriptObject function, int at, int stackIndex)
        {
            Contract.Assert(function.Type == ValueType.FUNCTION);

            FuncPart func = function.Value.RefPartHandle.ConverToFuncPart();

            func.UpVals[at] = RunEnvironment.Instance.LocalStack.GetVarFromBase(stackIndex);
        }
 internal void AddFileld(int index, ScriptObject obj)
 {
     Contract.Assert(Type == ValueType.TABLE);
     Value.RefPartHandle.ConverToTablePart().AddFileld(index, obj);
 }
 internal void AddInArray(ScriptObject obj)
 {
     Contract.Assert(Type == ValueType.TABLE);
     Value.RefPartHandle.ConverToTablePart().AddInArray(obj);
 }
 /// <summary>
 ///    根据对象判断其条件属性
 /// </summary>
 /// <param name="obj"></param>
 /// <returns></returns>
 public static bool ConverScrObjToBool(ScriptObject obj)
 {
     if(obj.Type == ValueType.NIL)    // nil 为false
     {
         return false;
     }
     if (obj.Type == ValueType.BOOLEAN)
     {
         return obj.Value.Boolean;
     }
     return true;
 }
        internal ScriptObject GetOrCreateFileld(ScriptObject index)
        {
            Contract.Assert(Type == ValueType.TABLE);

            TablePart table = Value.RefPartHandle.ConverToTablePart();

            ScriptObject s = null;

            switch (index.Type)
            {
                case ValueType.NUMBER:

                    int at = (int)index.Value.Number;

                    s = Value.RefPartHandle.ConverToTablePart().IndexAt(at);

                    if (s == null)
                    {
                        s = ScriptObject.CreateNil();
                    }
                    table.AddFileld(at, s);
                    break;

                case ValueType.STRING:

                    string key = index.Value.RefPartHandle.ConverToStringPart().Value;

                    s = table.TryGetValue(key);
                    if (s == null)
                    {
                        s = ScriptObject.CreateNil();
                    }
                    table.AddFileld(key, s);

                    break;

                default:
                    Contract.Assert(false);
                    break;
            }
            return s;
        }
 /// <summary>
 ///    产生一个bool
 /// </summary>
 /// <param name="boolean"></param>
 /// <returns></returns>
 internal static ScriptObject CreateBool(bool boolean)
 {
     ScriptObject s = new ScriptObject();
     s.Type = ValueType.BOOLEAN;
     s.Value.Boolean = boolean;
     return s;
 }
 /// <summary>
 ///    产生一个 nil
 /// </summary>
 /// <returns></returns>
 public static ScriptObject CreateNil()
 {
     ScriptObject s = new ScriptObject();
     s.Type = ValueType.NIL;
     return s;
 }
 /// <summary>
 ///    产生一个函数
 /// </summary>
 /// <param name="function"></param>
 /// <returns></returns>
 internal static ScriptObject CreateFunction(Action func, int argCount, bool isUncertainParameters)
 {
     ScriptObject s = new ScriptObject();
     s.Type = ValueType.FUNCTION;
     s.Value.RefPartHandle = RefPartBase.CreateFuncPart(func, argCount, isUncertainParameters);
     return s;
 }
 public void AddFileld(string fileldName, ScriptObject scriptValue)
 {
     _value[fileldName] = scriptValue;
 }
 /// <summary>
 ///    产生一个 num
 /// </summary>
 /// <param name="num"></param>
 /// <returns></returns>
 internal static ScriptObject CreateNum(double num)
 {
     ScriptObject s = new ScriptObject();
     s.Type = ValueType.NUMBER;
     s.Value.Number = num;
     return s;
 }
        internal void InvokeFunction(ScriptObject function,params ScriptObject[] args)
        {
            this.PushFunction(function);

            foreach (ScriptObject i in args)
            {
                this.PushFuncParameter(i);
            }

            this.InvokeFunction();
        }
 /// <summary>
 ///    拷贝一个ScriptObject
 /// </summary>
 internal static ScriptObject CreateScriptObject(ScriptObject obj)
 {
     ScriptObject s = new ScriptObject();
     Instructor.AssignVar(s, obj);
     return s;
 }
        /// <summary>
        ///    将函数参数压栈,准备调用函数
        /// </summary>
        /// <param name="parameter"></param>
        internal void PushFuncParameter(ScriptObject parameter)
        {
            Contract.Assert(parameter!=null);

            int funcIndex = _funcPushStack.Peek();

            FuncPart func = stack[funcIndex].Value.RefPartHandle.ConverToFuncPart();

            //当前栈中的函数参数小于函数参数大小
            if (Top - (funcIndex + 1) < func.ArgsCount)
            {
                Push(parameter);
            }
            else if (func.IsUncertainParameters == true)   //是不定参数
            {
                if (Top - (funcIndex + 1) == func.ArgsCount)
                {
                    ScriptObject s = ScriptObject.CreateTable();

                    stack.Add(s);
                }
                ScriptObject args = stack[Top - 1];
                args.AddInArray(parameter);
            }
            //否则,则省略掉传入参数
        }
 /// <summary>
 ///    产生一个字符串
 /// </summary>
 /// <param name="str"></param>
 /// <returns></returns>
 internal static ScriptObject CreateString(string value)
 {
     ScriptObject s = new ScriptObject();
     s.Type = ValueType.STRING;
     s.Value.RefPartHandle = RefPartBase.CreateStrPart(value);
     return s;
 }
        internal void SetReturn(ScriptObject scriptObject)
        {
            Contract.Assert(scriptObject!=null);

            Instructor.AssignVar(returnValue, scriptObject);
        }
 /// <summary>
 ///    产生一个表
 /// </summary>
 /// <returns></returns>
 internal static ScriptObject CreateTable()
 {
     ScriptObject s = new ScriptObject();
     s.Type = ValueType.TABLE;
     s.Value.RefPartHandle = RefPartBase.CreateTablePart();
     return s;
 }