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); }
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(); }
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); }