public ICQ_Expression Compiler_Expression_Lambda(IList <Token> tlist, ICQ_Environment content, int pos, int posend)
        {
            int b1;
            int fs1 = pos;
            int fe1 = FindCodeAny(tlist, ref fs1, out b1);
            CQ_Expression_Lambda value = new CQ_Expression_Lambda(pos, posend, tlist[pos].line, tlist[posend].line);

            int testbegin = fs1 + 1;

            if (b1 != 1)
            {
                return(null);
            }
            //(xxx)=>{...}
            CQ_Expression_Block block = new CQ_Expression_Block(fs1, fe1, tlist[fs1].line, tlist[fe1].line);

            do
            {
                int fe2 = FindCodeAny(tlist, ref testbegin, out b1);


                ICQ_Expression subvalue;
                bool           succ = Compiler_Expression(tlist, content, testbegin, fe2, out subvalue);
                if (!succ)
                {
                    break;
                }
                if (subvalue != null)
                {
                    block.listParam.Add(subvalue);
                    testbegin = fe2 + 2;
                }
                else
                {
                    block.listParam.Add(null);
                    testbegin = fe2 + 2;
                }
            }while (testbegin <= fe1);

            value.listParam.Add(block);
            //(...)=>{}
            ICQ_Expression subvalueblock;

            int  b2;
            int  fs2    = fe1 + 2;
            int  fecode = FindCodeAny(tlist, ref fs2, out b2);
            bool succ2  = Compiler_Expression_Block(tlist, content, fs2, fecode, out subvalueblock);

            if (succ2)
            {
                //value.tokenEnd = fecode;
                //value.lineEnd = tlist[fecode].line;
                value.listParam.Add(subvalueblock);
                return(value);
            }
            return(null);
        }
        //可以搞出Block
        public static bool Compiler_Expression_Block(IList <Token> tlist, int pos, int posend, out ICQ_Expression value)
        {
            int begin = pos;

            value = null;
            List <ICQ_Expression> values = new List <ICQ_Expression>();
            int end = 0;

            do
            {
                if (tlist[begin].type == TokenType.COMMENT)
                {
                    begin++;
                    continue;
                }
                if (tlist[begin].type == TokenType.PUNCTUATION && tlist[begin].text == ";")
                {
                    begin++;
                    continue;
                }
                int bdep;
                //脱一次壳
                end = FindCodeInBlock(tlist, ref begin, out bdep);

                if (end > posend)
                {
                    end = posend;
                }
                int expend   = end;
                int expbegin = begin;
                if (expbegin > expend)
                {
                    //LogError(tlist, "括号块识别失败", expbegin, expend);
                    return(true);
                }
                if (bdep == 2) //编译块表达式
                {
                    expbegin++;
                    expend--;
                    ICQ_Expression subvalue;
                    bool           bsucc = Compiler_Expression_Block(tlist, expbegin, expend, out subvalue);
                    if (bsucc)
                    {
                        if (subvalue != null)
                        {
                            values.Add(subvalue);
                        }
                    }
                    else
                    {
                        LogError(tlist, "表达式编译失败", expbegin, expend);
                        return(false);
                    }
                }
                else
                {
                    ICQ_Expression subvalue;
                    bool           bsucc = Compiler_Expression(tlist, expbegin, expend, out subvalue);
                    if (bsucc)
                    {
                        if (subvalue != null)
                        {
                            values.Add(subvalue);
                        }
                    }
                    else
                    {
                        LogError(tlist, "表达式编译失败", expbegin, expend);
                        return(false);
                    }
                }

                begin = end + 1;
            }while (begin <= posend);
            if (values.Count == 1)
            {
                value = values[0];
            }
            else if (values.Count > 1)
            {
                CQ_Expression_Block block = new CQ_Expression_Block(pos, end, tlist[pos].line, tlist[end].line);
                foreach (var v in values)
                {
                    block._expressions.Add(v);
                }
                value = block;
            }
            return(true);
        }
Example #3
0
        public CQ_Value MemberCall(CQ_Content contentParent, object object_this, string func, CQ_Value[] _params, MethodCache cache)
        {
            if (cache != null)
            {
                cache.cachefail = true;
            }
            Function funccache = null;

            if (this.functions.TryGetValue(func, out funccache))
            {
                if (funccache.bStatic == false)
                {
                    CQ_Content content = CQ_ObjPool.PopContent();
                    content.CallType = this;
                    content.CallThis = object_this as CQ_ClassInstance;

#if CQUARK_DEBUG
                    content.function = func;
                    contentParent.InStack(content);//把这个上下文推给上层的上下文,这样如果崩溃是可以一层层找到原因的
#endif
                    for (int i = 0; i < funccache._paramtypes.Count; i++)
                    {
                        //content.DefineAndSet(funccache._paramnames[i], funccache._paramtypes[i].typeBridge, _params[i].GetValue());
                        content.DefineAndSet(funccache._paramnames[i], _params[i].typeBridge, _params[i]);
                    }

                    //如果返回值是IEnumerator的话,这里把方法返回出来
                    if (funccache._returntype != null && funccache._returntype.typeBridge.type == typeof(IEnumerator))
                    {
                        CQ_Value            ienumerator = new CQ_Value();
                        CQ_Expression_Block funcCQ      = funccache.expr_runtime as CQ_Expression_Block;
                        funcCQ.callObj = content;
                        ienumerator.SetObject(typeof(CQ_Expression_Block), funcCQ);
                        return(ienumerator);
                    }


                    CQ_Value value   = CQ_Value.Null;
                    var      funcobj = funccache;
                    if (this.bInterface)
                    {
                        content.CallType = (object_this as CQ_ClassInstance).type;
                        funcobj          = (object_this as CQ_ClassInstance).type.functions[func];
                    }
                    if (funcobj.expr_runtime != null)
                    {
                        value = funcobj.expr_runtime.ComputeValue(content);
                    }
#if CQUARK_DEBUG
                    contentParent.OutStack(content);
#endif
                    CQ_ObjPool.PushContent(content);
                    return(value);
                }
            }
            else if (this.members.ContainsKey(func))
            {
                if (this.members[func].bStatic == false)
                {
                    Delegate dele = (object_this as CQ_ClassInstance).member[func].GetObject() as Delegate;
                    if (dele != null)
                    {
                        CQ_Value value = new CQ_Value();
                        object[] objs  = new object[_params.Length];
                        for (int i = 0; i < _params.Length; i++)
                        {
                            objs[i] = _params[i].GetObject();
                        }
                        object obj = dele.DynamicInvoke(objs);
                        if (obj == null)
                        {
                            return(CQ_Value.Null);
                        }
                        else
                        {
                            value.SetObject(obj.GetType(), obj);
                            return(value);
                        }
                    }
                }
            }
            throw new NotImplementedException();
        }
Example #4
0
        public CQ_Value ComputeValue(CQ_Content content)
        {
#if CQUARK_DEBUG
            content.InStack(this);
#endif
            CQ_Value parent = _expressions[0].ComputeValue(content);

#if CQUARK_DEBUG
            if (parent == CQ_Value.Null)
            {
                throw new Exception("调用空对象的方法:" + _expressions[0].ToString() + ":" + ToString());
            }
#endif


            CQ_Value[] parameters = CQ_ObjPool.PopArray(_expressions.Count - 1);
            for (int i = 0; i < _expressions.Count - 1; i++)
            {
                parameters[i] = _expressions[i + 1].ComputeValue(content);
            }

            CQ_Value value = CQ_Value.Null;

            //这几行是为了快速获取Unity的静态变量,而不需要反射
            object obj = parent.GetObject();
            if (!Wrap.MemberCall(parent.m_type, obj, functionName, parameters, out value))
            {
                //TODO 要么注册所有基本类型(bool,int,string...)要么这里特殊处理
                if (functionName == "ToString" && parameters.Length == 0)
                {
                    CQ_Value ret = new CQ_Value();
                    ret.SetObject(typeof(string), obj.ToString());
                    return(ret);
                }
                else if (obj is UnityEngine.MonoBehaviour && functionName == "StartCoroutine" &&
                         parameters.Length >= 1 && parameters[0].GetObject() is CQ_Expression_Block)
                {
                    //从西瓜调用的ClassSystem.StartCoroutine(CquarkMethod());不需要走cache
                    UnityEngine.MonoBehaviour mb   = obj as UnityEngine.MonoBehaviour;
                    CQ_Expression_Block       call = parameters[0].GetObject()  as CQ_Expression_Block;

                    CQ_Value ret = new CQ_Value();
                    ret.SetObject(typeof(UnityEngine.Coroutine),
                                  mb.StartCoroutine(call.callObj.CallType.CoroutineCall(call, call.callObj, mb)));
                    return(ret);
                }
                else
                {
                    var iclass = CQuark.AppDomain.GetITypeByCQValue(parent)._class;
                    if (cache == null || cache.cachefail)
                    {
                        cache = new MethodCache();
                        value = iclass.MemberCall(content, obj, functionName, parameters, cache);
                    }
                    else
                    {
                        value = iclass.MemberCallCache(content, obj, parameters, cache);
                    }
                }
            }


#if CQUARK_DEBUG
            content.OutStack(this);
#endif
            CQ_ObjPool.PushArray(parameters);
            return(value);
        }