usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Linq.Expressions;usingSystem.Reflection;usingSystem.Reflection.Emit;usingSystem.Text;usingSystem.Threading;namespaceHh.Mes.Common.Infrastructure{publicstaticclassDynamicQueryable{publicstaticIQueryable<T>Where<T>(thisIQueryable<T>source,stringpredicate,paramsobject[]values){return(IQueryable<T>)Where((IQueryable)source,predicate,values);}publicstaticIQueryableWhere(thisIQueryablesource,stringpredicate,paramsobject[]values){if(source==null)thrownewArgumentNullException("source");if(predicate==null)thrownewArgumentNullException("predicate");LambdaExpressionlambda=DynamicExpression.ParseLambda(source.ElementType,typeof(bool),predicate,values);returnsource.Provider.CreateQuery(Expression.Call(typeof(Queryable),"Where",newType[]{source.ElementType},source.Expression,Expression.Quote(lambda)));}publicstaticIQueryableSelect(thisIQueryablesource,stringselector,paramsobject[]values){if(source==null)thrownewArgumentNullException("source");if(selector==null)thrownewArgumentNullException("selector");LambdaExpressionlambda=DynamicExpression.ParseLambda(source.ElementType,null,selector,values);returnsource.Provider.CreateQuery(Expression.Call(typeof(Queryable),"Select",newType[]{source.ElementType,lambda.Body.Type},source.Expression,Expression.Quote(lambda)));}publicstaticIQueryable<T>OrderBy<T>(thisIQueryable<T>source,stringordering,paramsobject[]values){return(IQueryable<T>)OrderBy((IQueryable)source,ordering,values);}publicstaticIQueryable<T>ThenBy<T>(thisIQueryable<T>source,stringordering,paramsobject[]values){return(IQueryable<T>)ThenBy((IQueryable)source,ordering,values);}publicstaticIQueryableThenBy(thisIQueryablesource,stringordering,paramsobject[]values){if(source==null)thrownewArgumentNullException("source");if(ordering==null)thrownewArgumentNullException("ordering");ParameterExpression[]parameters=newParameterExpression[]{Expression.Parameter(source.ElementType,"")};ExpressionParserparser=newExpressionParser(parameters,ordering,values);IEnumerable<DynamicOrdering>orderings=parser.ParseOrdering();ExpressionqueryExpr=source.Expression;stringmethodAsc="ThenBy";stringmethodDesc="ThenByDescending";foreach(DynamicOrderingoinorderings){queryExpr=Expression.Call(typeof(Queryable),o.Ascending?methodAsc:methodDesc,newType[]{source.ElementType,o.Selector.Type},queryExpr,Expression.Quote(Expression.Lambda(o.Selector,parameters)));}returnsource.Provider.CreateQuery(queryExpr);}publicstaticIQueryableOrderBy(thisIQueryablesource,stringordering,paramsobject[]values){if(source==null)thrownewArgumentNullException("source");if(ordering==null)thrownewArgumentNullException("ordering");ParameterExpression[]parameters=newParameterExpression[]{Expression.Parameter(source.ElementType,"")};ExpressionParserparser=newExpressionParser(parameters,ordering,values);IEnumerable<DynamicOrdering>orderings=parser.ParseOrdering();ExpressionqueryExpr=source.Expression;stringmethodAsc="OrderBy";stringmethodDesc="OrderByDescending";foreach(DynamicOrderingoinorderings){queryExpr=Expression.Call(typeof(Queryable),o.Ascending?methodAsc:methodDesc,newType[]{source.ElementType,o.Selector.Type},queryExpr,Expression.Quote(Expression.Lambda(o.Selector,parameters)));methodAsc="ThenBy";methodDesc="ThenByDescending";}returnsource.Provider.CreateQuery(queryExpr);}publicstaticIQueryable<T>OrderBy<T>(thisIQueryable<T>source,stringpropertyName,boolascending)whereT:class{Typetype=typeof(T);PropertyInfoproperty=type.GetProperty(propertyName);if(property==null)thrownewArgumentException("propertyName","Not Exist");ParameterExpressionparam=Expression.Parameter(type,"p");ExpressionpropertyAccessExpression=Expression.MakeMemberAccess(param,property);LambdaExpressionorderByExpression=Expression.Lambda(propertyAccessExpression,param);stringmethodName=ascending?"OrderBy":"OrderByDescending";MethodCallExpressionresultExp=Expression.Call(typeof(Queryable),methodName,newType[]{type,property.PropertyType},source.Expression,Expression.Quote(orderByExpression));returnsource.Provider.CreateQuery<T>(resultExp);}publicstaticIQueryableTake(thisIQueryablesource,intcount){if(source==null)thrownewArgumentNullException("source");returnsource.Provider.CreateQuery(Expression.Call(typeof(Queryable),"Take",newType[]{source.ElementType},source.Expression,Expression.Constant(count)));}publicstaticIQueryableSkip(thisIQueryablesource,intcount){if(source==null)thrownewArgumentNullException("source");returnsource.Provider.CreateQuery(Expression.Call(typeof(Queryable),"Skip",newType[]{source.ElementType},source.Expression,Expression.Constant(count)));}publicstaticIQueryableGroupBy(thisIQueryablesource,stringkeySelector,stringelementSelector,paramsobject[]values){if(source==null)thrownewArgumentNullException("source");if(keySelector==null)thrownewArgumentNullException("keySelector");if(elementSelector==null)thrownewArgumentNullException("elementSelector");LambdaExpressionkeyLambda=DynamicExpression.ParseLambda(source.ElementType,null,keySelector,values);LambdaExpressionelementLambda=DynamicExpression.ParseLambda(source.ElementType,null,elementSelector,values);returnsource.Provider.CreateQuery(Expression.Call(typeof(Queryable),"GroupBy",newType[]{source.ElementType,keyLambda.Body.Type,elementLambda.Body.Type},source.Expression,Expression.Quote(keyLambda),Expression.Quote(elementLambda)));}publicstaticboolAny(thisIQueryablesource){if(source==null)thrownewArgumentNullException("source");return(bool)source.Provider.Execute(Expression.Call(typeof(Queryable),"Any",newType[]{source.ElementType},source.Expression));}publicstaticintCount(thisIQueryablesource){if(source==null)thrownewArgumentNullException("source");return(int)source.Provider.Execute(Expression.Call(typeof(Queryable),"Count",newType[]{source.ElementType},source.Expression));}}publicabstractclassDynamicClass{publicoverridestringToString(){PropertyInfo[]props=this.GetType().GetProperties(BindingFlags.Instance|BindingFlags.Public);StringBuildersb=newStringBuilder();sb.Append("{");for(inti=0;i<props.Length;i++){if(i>0)sb.Append(", ");sb.Append(props[i].Name);sb.Append("=");sb.Append(props[i].GetValue(this,null));}sb.Append("}");returnsb.ToString();}}publicclassDynamicProperty{stringname;Typetype;publicDynamicProperty(stringname,Typetype){if(name==null)thrownewArgumentNullException("name");if(type==null)thrownewArgumentNullException("type");this.name=name;this.type=type;}publicstringName{get{returnname;}}publicTypeType{get{returntype;}}}publicstaticclassDynamicExpression{publicstaticExpressionParse(TyperesultType,stringexpression,paramsobject[]values){ExpressionParserparser=newExpressionParser(null,expression,values);returnparser.Parse(resultType);}publicstaticLambdaExpressionParseLambda(TypeitType,TyperesultType,stringexpression,paramsobject[]values){returnParseLambda(newParameterExpression[]{Expression.Parameter(itType,"")},resultType,expression,values);}publicstaticLambdaExpressionParseLambda(ParameterExpression[]parameters,TyperesultType,stringexpression,paramsobject[]values){ExpressionParserparser=newExpressionParser(parameters,expression,values);returnExpression.Lambda(parser.Parse(resultType),parameters);}publicstaticExpression<Func<T,S>>ParseLambda<T,S>(stringexpression,paramsobject[]values){return(Expression<Func<T,S>>)ParseLambda(typeof(T),typeof(S),expression,values);}publicstaticTypeCreateClass(paramsDynamicProperty[]properties){returnClassFactory.Instance.GetDynamicClass(properties);}publicstaticTypeCreateClass(IEnumerable<DynamicProperty>properties){returnClassFactory.Instance.GetDynamicClass(properties);}}internalclassDynamicOrdering{publicExpressionSelector;publicboolAscending;}internalclassSignature:IEquatable<Signature>{publicDynamicProperty[]properties;publicinthashCode;publicSignature(IEnumerable<DynamicProperty>properties){this.properties=properties.ToArray();hashCode=0;foreach(DynamicPropertypinproperties){hashCode^=p.Name.GetHashCode()^p.Type.GetHashCode();}}publicoverrideintGetHashCode(){returnhashCode;}publicoverrideboolEquals(objectobj){returnobjisSignature?Equals((Signature)obj):false;}publicboolEquals(Signatureother){if(properties.Length!=other.properties.Length)returnfalse;for(inti=0;i<properties.Length;i++){if(properties[i].Name!=other.properties[i].Name||properties[i].Type!=other.properties[i].Type)returnfalse;}returntrue;}}internalclassClassFactory{publicstaticreadonlyClassFactoryInstance=newClassFactory();staticClassFactory(){}//TriggerlazyinitializationofstaticfieldsModuleBuildermodule;Dictionary<Signature,Type>classes;intclassCount;ReaderWriterLockrwLock;privateClassFactory(){AssemblyNamename=newAssemblyName("DynamicClasses");AssemblyBuilderassembly=AssemblyBuilder.DefineDynamicAssembly(name,AssemblyBuilderAccess.Run);//AssemblyBuilderassembly=AppDomain.CurrentDomain.DefineDynamicAssembly(name,AssemblyBuilderAccess.Run);#ifENABLE_LINQ_PARTIAL_TRUSTnewReflectionPermission(PermissionState.Unrestricted).Assert();#endiftry{module=assembly.DefineDynamicModule("Module");}finally{#ifENABLE_LINQ_PARTIAL_TRUSTPermissionSet.RevertAssert();#endif}classes=newDictionary<Signature,Type>();rwLock=newReaderWriterLock();}publicTypeGetDynamicClass(IEnumerable<DynamicProperty>properties){rwLock.AcquireReaderLock(Timeout.Infinite);try{Signaturesignature=newSignature(properties);Typetype;if(!classes.TryGetValue(signature,outtype)){type=CreateDynamicClass(signature.properties);classes.Add(signature,type);}returntype;}finally{rwLock.ReleaseReaderLock();}}TypeCreateDynamicClass(DynamicProperty[]properties){LockCookiecookie=rwLock.UpgradeToWriterLock(Timeout.Infinite);try{stringtypeName="DynamicClass"+(classCount+1);#ifENABLE_LINQ_PARTIAL_TRUSTnewReflectionPermission(PermissionState.Unrestricted).Assert();#endiftry{TypeBuildertb=this.module.DefineType(typeName,TypeAttributes.Class|TypeAttributes.Public,typeof(DynamicClass));FieldInfo[]fields=GenerateProperties(tb,properties);GenerateEquals(tb,fields);GenerateGetHashCode(tb,fields);Typeresult=tb.CreateType();classCount++;returnresult;}finally{#ifENABLE_LINQ_PARTIAL_TRUSTPermissionSet.RevertAssert();#endif}}finally{rwLock.DowngradeFromWriterLock(refcookie);}}FieldInfo[]GenerateProperties(TypeBuildertb,DynamicProperty[]properties){FieldInfo[]fields=newFieldBuilder[properties.Length];for(inti=0;i<properties.Length;i++){DynamicPropertydp=properties[i];FieldBuilderfb=tb.DefineField("_"+dp.Name,dp.Type,FieldAttributes.Private);PropertyBuilderpb=tb.DefineProperty(dp.Name,PropertyAttributes.HasDefault,dp.Type,null);MethodBuildermbGet=tb.DefineMethod("get_"+dp.Name,MethodAttributes.Public|MethodAttributes.SpecialName|MethodAttributes.HideBySig,dp.Type,Type.EmptyTypes);ILGeneratorgenGet=mbGet.GetILGenerator();genGet.Emit(OpCodes.Ldarg_0);genGet.Emit(OpCodes.Ldfld,fb);genGet.Emit(OpCodes.Ret);MethodBuildermbSet=tb.DefineMethod("set_"+dp.Name,MethodAttributes.Public|MethodAttributes.SpecialName|MethodAttributes.HideBySig,null,newType[]{dp.Type});ILGeneratorgenSet=mbSet.GetILGenerator();genSet.Emit(OpCodes.Ldarg_0);genSet.Emit(OpCodes.Ldarg_1);genSet.Emit(OpCodes.Stfld,fb);genSet.Emit(OpCodes.Ret);pb.SetGetMethod(mbGet);pb.SetSetMethod(mbSet);fields[i]=fb;}returnfields;}voidGenerateEquals(TypeBuildertb,FieldInfo[]fields){MethodBuildermb=tb.DefineMethod("Equals",MethodAttributes.Public|MethodAttributes.ReuseSlot|MethodAttributes.Virtual|MethodAttributes.HideBySig,typeof(bool),newType[]{typeof(object)});ILGeneratorgen=mb.GetILGenerator();LocalBuilderother=gen.DeclareLocal(tb);Labelnext=gen.DefineLabel();gen.Emit(OpCodes.Ldarg_1);gen.Emit(OpCodes.Isinst,tb);gen.Emit(OpCodes.Stloc,other);gen.Emit(OpCodes.Ldloc,other);gen.Emit(OpCodes.Brtrue_S,next);gen.Emit(OpCodes.Ldc_I4_0);gen.Emit(OpCodes.Ret);gen.MarkLabel(next);foreach(FieldInfofieldinfields){Typeft=field.FieldType;Typect=typeof(EqualityComparer<>).MakeGenericType(ft);next=gen.DefineLabel();gen.EmitCall(OpCodes.Call,ct.GetMethod("get_Default"),null);gen.Emit(OpCodes.Ldarg_0);gen.Emit(OpCodes.Ldfld,field);gen.Emit(OpCodes.Ldloc,other);gen.Emit(OpCodes.Ldfld,field);gen.EmitCall(OpCodes.Callvirt,ct.GetMethod("Equals",newType[]{ft,ft}),null);gen.Emit(OpCodes.Brtrue_S,next);gen.Emit(OpCodes.Ldc_I4_0);gen.Emit(OpCodes.Ret);gen.MarkLabel(next);}gen.Emit(OpCodes.Ldc_I4_1);gen.Emit(OpCodes.Ret);}voidGenerateGetHashCode(TypeBuildertb,FieldInfo[]fields){MethodBuildermb=tb.DefineMethod("GetHashCode",MethodAttributes.Public|MethodAttributes.ReuseSlot|MethodAttributes.Virtual|MethodAttributes.HideBySig,typeof(int),Type.EmptyTypes);ILGeneratorgen=mb.GetILGenerator();gen.Emit(OpCodes.Ldc_I4_0);foreach(FieldInfofieldinfields){Typeft=field.FieldType;Typect=typeof(EqualityComparer<>).MakeGenericType(ft);gen.EmitCall(OpCodes.Call,ct.GetMethod("get_Default"),null);gen.Emit(OpCodes.Ldarg_0);gen.Emit(OpCodes.Ldfld,field);gen.EmitCall(OpCodes.Callvirt,ct.GetMethod("GetHashCode",newType[]{ft}),null);gen.Emit(OpCodes.Xor);}gen.Emit(OpCodes.Ret);}}publicsealedclassParseException:Exception{intposition;publicParseException(stringmessage,intposition):base(message){this.position=position;}publicintPosition{get{returnposition;}}publicoverridestringToString(){returnstring.Format(Res.ParseExceptionFormat,Message,position);}}internalclassExpressionParser{structToken{publicTokenIdid;publicstringtext;publicintpos;}enumTokenId{Unknown,End,Identifier,StringLiteral,IntegerLiteral,RealLiteral,Exclamation,Percent,Amphersand,OpenParen,CloseParen,Asterisk,Plus,Comma,Minus,Dot,Slash,Colon,LessThan,Equal,GreaterThan,Question,OpenBracket,CloseBracket,Bar,ExclamationEqual,DoubleAmphersand,LessThanEqual,LessGreater,DoubleEqual,GreaterThanEqual,DoubleBar}interfaceILogicalSignatures{voidF(boolx,booly);voidF(bool?x,bool?y);}interfaceIArithmeticSignatures{voidF(intx,inty);voidF(uintx,uinty);voidF(longx,longy);voidF(ulongx,ulongy);voidF(floatx,floaty);voidF(doublex,doubley);voidF(decimalx,decimaly);voidF(int?x,int?y);voidF(uint?x,uint?y);voidF(long?x,long?y);voidF(ulong?x,ulong?y);voidF(float?x,float?y);voidF(double?x,double?y);voidF(decimal?x,decimal?y);}interfaceIRelationalSignatures:IArithmeticSignatures{voidF(stringx,stringy);voidF(charx,chary);voidF(DateTimex,DateTimey);voidF(TimeSpanx,TimeSpany);voidF(char?x,char?y);voidF(DateTime?x,DateTime?y);voidF(TimeSpan?x,TimeSpan?y);}interfaceIEqualitySignatures:IRelationalSignatures{voidF(boolx,booly);voidF(bool?x,bool?y);}interfaceIAddSignatures:IArithmeticSignatures{voidF(DateTimex,TimeSpany);voidF(TimeSpanx,TimeSpany);voidF(DateTime?x,TimeSpan?y);voidF(TimeSpan?x,TimeSpan?y);}interfaceISubtractSignatures:IAddSignatures{voidF(DateTimex,DateTimey);voidF(DateTime?x,DateTime?y);}interfaceINegationSignatures{voidF(intx);voidF(longx);voidF(floatx);voidF(doublex);voidF(decimalx);voidF(int?x);voidF(long?x);voidF(float?x);voidF(double?x);voidF(decimal?x);}interfaceINotSignatures{voidF(boolx);voidF(bool?x);}interfaceIEnumerableSignatures{voidWhere(boolpredicate);voidAny();voidAny(boolpredicate);voidAll(boolpredicate);voidCount();voidCount(boolpredicate);voidMin(objectselector);voidMax(objectselector);voidSum(intselector);voidSum(int?selector);voidSum(longselector);voidSum(long?selector);voidSum(floatselector);voidSum(float?selector);voidSum(doubleselector);voidSum(double?selector);voidSum(decimalselector);voidSum(decimal?selector);voidAverage(intselector);voidAverage(int?selector);voidAverage(longselector);voidAverage(long?selector);voidAverage(floatselector);voidAverage(float?selector);voidAverage(doubleselector);voidAverage(double?selector);voidAverage(decimalselector);voidAverage(decimal?selector);}staticreadonlyType[]predefinedTypes={typeof(Object),typeof(Boolean),typeof(Char),typeof(String),typeof(SByte),typeof(Byte),typeof(Int16),typeof(UInt16),typeof(Int32),typeof(UInt32),typeof(Int64),typeof(UInt64),typeof(Single),typeof(Double),typeof(Decimal),typeof(DateTime),typeof(TimeSpan),typeof(Guid),typeof(Math),typeof(Convert)};staticreadonlyExpressiontrueLiteral=Expression.Constant(true);staticreadonlyExpressionfalseLiteral=Expression.Constant(false);staticreadonlyExpressionnullLiteral=Expression.Constant(null);staticreadonlystringkeywordIt="it";staticreadonlystringkeywordIif="iif";staticreadonlystringkeywordNew="new";staticDictionary<string,object>keywords;Dictionary<string,object>symbols;IDictionary<string,object>externals;Dictionary<Expression,string>literals;ParameterExpressionit;stringtext;inttextPos;inttextLen;charch;Tokentoken;publicExpressionParser(ParameterExpression[]parameters,stringexpression,object[]values){if(expression==null)thrownewArgumentNullException("expression");if(keywords==null)keywords=CreateKeywords();symbols=newDictionary<string,object>(StringComparer.OrdinalIgnoreCase);literals=newDictionary<Expression,string>();if(parameters!=null)ProcessParameters(parameters);if(values!=null)ProcessValues(values);text=expression;textLen=text.Length;SetTextPos(0);NextToken();}voidProcessParameters(ParameterExpression[]parameters){foreach(ParameterExpressionpeinparameters)if(!String.IsNullOrEmpty(pe.Name))AddSymbol(pe.Name,pe);if(parameters.Length==1&&String.IsNullOrEmpty(parameters[0].Name))it=parameters[0];}voidProcessValues(object[]values){for(inti=0;i<values.Length;i++){objectvalue=values[i];if(i==values.Length-1&&valueisIDictionary<string,object>){externals=(IDictionary<string,object>)value;}else{AddSymbol("@"+i.ToString(System.Globalization.CultureInfo.InvariantCulture),value);}}}voidAddSymbol(stringname,objectvalue){if(symbols.ContainsKey(name))throwParseError(Res.DuplicateIdentifier,name);symbols.Add(name,value);}publicExpressionParse(TyperesultType){intexprPos=token.pos;Expressionexpr=ParseExpression();if(resultType!=null)if((expr=PromoteExpression(expr,resultType,true))==null)throwParseError(exprPos,Res.ExpressionTypeMismatch,GetTypeName(resultType));ValidateToken(TokenId.End,Res.SyntaxError);returnexpr;}#pragmawarningdisable0219publicIEnumerable<DynamicOrdering>ParseOrdering(){List<DynamicOrdering>orderings=newList<DynamicOrdering>();while(true){Expressionexpr=ParseExpression();boolascending=true;if(TokenIdentifierIs("asc")||TokenIdentifierIs("ascending")){NextToken();}elseif(TokenIdentifierIs("desc")||TokenIdentifierIs("descending")){NextToken();ascending=false;}orderings.Add(newDynamicOrdering{Selector=expr,Ascending=ascending});if(token.id!=TokenId.Comma)break;NextToken();}ValidateToken(TokenId.End,Res.SyntaxError);returnorderings;}#pragmawarningrestore0219//?:operatorExpressionParseExpression(){interrorPos=token.pos;Expressionexpr=ParseLogicalOr();if(token.id==TokenId.Question){NextToken();Expressionexpr1=ParseExpression();ValidateToken(TokenId.Colon,Res.ColonExpected);NextToken();Expressionexpr2=ParseExpression();expr=GenerateConditional(expr,expr1,expr2,errorPos);}returnexpr;}//||,oroperatorExpressionParseLogicalOr(){Expressionleft=ParseLogicalAnd();while(token.id==TokenId.DoubleBar||TokenIdentifierIs("or")){Tokenop=token;NextToken();Expressionright=ParseLogicalAnd();CheckAndPromoteOperands(typeof(ILogicalSignatures),op.text,refleft,refright,op.pos);left=Expression.OrElse(left,right);}returnleft;}//&&,andoperatorExpressionParseLogicalAnd(){Expressionleft=ParseComparison();while(token.id==TokenId.DoubleAmphersand||TokenIdentifierIs("and")){Tokenop=token;NextToken();Expressionright=ParseComparison();CheckAndPromoteOperands(typeof(ILogicalSignatures),op.text,refleft,refright,op.pos);left=Expression.AndAlso(left,right);}returnleft;}//=,==,!=,<>,>,>=,<,<=operatorsExpressionParseComparison(){Expressionleft=ParseAdditive();while(token.id==TokenId.Equal||token.id==TokenId.DoubleEqual||token.id==TokenId.ExclamationEqual||token.id==TokenId.LessGreater||token.id==TokenId.GreaterThan||token.id==TokenId.GreaterThanEqual||token.id==TokenId.LessThan||token.id==TokenId.LessThanEqual){Tokenop=token;NextToken();Expressionright=ParseAdditive();boolisEquality=op.id==TokenId.Equal||op.id==TokenId.DoubleEqual||op.id==TokenId.ExclamationEqual||op.id==TokenId.LessGreater;if(isEquality&&!left.Type.IsValueType&&!right.Type.IsValueType){if(left.Type!=right.Type){if(left.Type.IsAssignableFrom(right.Type)){right=Expression.Convert(right,left.Type);}elseif(right.Type.IsAssignableFrom(left.Type)){left=Expression.Convert(left,right.Type);}else{throwIncompatibleOperandsError(op.text,left,right,op.pos);}}}elseif(IsEnumType(left.Type)||IsEnumType(right.Type)){if(left.Type!=right.Type){Expressione;if((e=PromoteExpression(right,left.Type,true))!=null){right=e;}elseif((e=PromoteExpression(left,right.Type,true))!=null){left=e;}else{throwIncompatibleOperandsError(op.text,left,right,op.pos);}}}else{CheckAndPromoteOperands(isEquality?typeof(IEqualitySignatures):typeof(IRelationalSignatures),op.text,refleft,refright,op.pos);}switch(op.id){caseTokenId.Equal:caseTokenId.DoubleEqual:left=GenerateEqual(left,right);break;caseTokenId.ExclamationEqual:caseTokenId.LessGreater:left=GenerateNotEqual(left,right);break;caseTokenId.GreaterThan:left=GenerateGreaterThan(left,right);break;caseTokenId.GreaterThanEqual:left=GenerateGreaterThanEqual(left,right);break;caseTokenId.LessThan:left=GenerateLessThan(left,right);break;caseTokenId.LessThanEqual:left=GenerateLessThanEqual(left,right);break;}}returnleft;}//+,-,&operatorsExpressionParseAdditive(){Expressionleft=ParseMultiplicative();while(token.id==TokenId.Plus||token.id==TokenId.Minus||token.id==TokenId.Amphersand){Tokenop=token;NextToken();Expressionright=ParseMultiplicative();switch(op.id){caseTokenId.Plus:if(left.Type==typeof(string)||right.Type==typeof(string))gotocaseTokenId.Amphersand;CheckAndPromoteOperands(typeof(IAddSignatures),op.text,refleft,refright,op.pos);left=GenerateAdd(left,right);break;caseTokenId.Minus:CheckAndPromoteOperands(typeof(ISubtractSignatures),op.text,refleft,refright,op.pos);left=GenerateSubtract(left,right);break;caseTokenId.Amphersand:left=GenerateStringConcat(left,right);break;}}returnleft;}//*,/,%,modoperatorsExpressionParseMultiplicative(){Expressionleft=ParseUnary();while(token.id==TokenId.Asterisk||token.id==TokenId.Slash||token.id==TokenId.Percent||TokenIdentifierIs("mod")){Tokenop=token;NextToken();Expressionright=ParseUnary();CheckAndPromoteOperands(typeof(IArithmeticSignatures),op.text,refleft,refright,op.pos);switch(op.id){caseTokenId.Asterisk:left=Expression.Multiply(left,right);break;caseTokenId.Slash:left=Expression.Divide(left,right);break;caseTokenId.Percent:caseTokenId.Identifier:left=Expression.Modulo(left,right);break;}}returnleft;}//-,!,notunaryoperatorsExpressionParseUnary(){if(token.id==TokenId.Minus||token.id==TokenId.Exclamation||TokenIdentifierIs("not")){Tokenop=token;NextToken();if(op.id==TokenId.Minus&&(token.id==TokenId.IntegerLiteral||token.id==TokenId.RealLiteral)){token.text="-"+token.text;token.pos=op.pos;returnParsePrimary();}Expressionexpr=ParseUnary();if(op.id==TokenId.Minus){CheckAndPromoteOperand(typeof(INegationSignatures),op.text,refexpr,op.pos);expr=Expression.Negate(expr);}else{CheckAndPromoteOperand(typeof(INotSignatures),op.text,refexpr,op.pos);expr=Expression.Not(expr);}returnexpr;}returnParsePrimary();}ExpressionParsePrimary(){Expressionexpr=ParsePrimaryStart();while(true){if(token.id==TokenId.Dot){NextToken();expr=ParseMemberAccess(null,expr);}elseif(token.id==TokenId.OpenBracket){expr=ParseElementAccess(expr);}else{break;}}returnexpr;}ExpressionParsePrimaryStart(){switch(token.id){caseTokenId.Identifier:returnParseIdentifier();caseTokenId.StringLiteral:returnParseStringLiteral();caseTokenId.IntegerLiteral:returnParseIntegerLiteral();caseTokenId.RealLiteral:returnParseRealLiteral();caseTokenId.OpenParen:returnParseParenExpression();default:throwParseError(Res.ExpressionExpected);}}ExpressionParseStringLiteral(){ValidateToken(TokenId.StringLiteral);charquote=token.text[0];strings=token.text.Substring(1,token.text.Length-2);intstart=0;while(true){inti=s.IndexOf(quote,start);if(i<0)break;s=s.Remove(i,1);start=i+1;}//if(quote=='\''){//if(s.Length!=1)//throwParseError(Res.InvalidCharacterLiteral);//NextToken();//returnCreateLiteral(s[0],s);//}NextToken();returnCreateLiteral(s,s);}ExpressionParseIntegerLiteral(){ValidateToken(TokenId.IntegerLiteral);stringtext=token.text;if(text[0]!='-'){ulongvalue;if(!UInt64.TryParse(text,outvalue))throwParseError(Res.InvalidIntegerLiteral,text);NextToken();if(value<=(ulong)Int32.MaxValue)returnCreateLiteral((int)value,text);if(value<=(ulong)UInt32.MaxValue)returnCreateLiteral((uint)value,text);if(value<=(ulong)Int64.MaxValue)returnCreateLiteral((long)value,text);returnCreateLiteral(value,text);}else{longvalue;if(!Int64.TryParse(text,outvalue))throwParseError(Res.InvalidIntegerLiteral,text);NextToken();if(value>=Int32.MinValue&&value<=Int32.MaxValue)returnCreateLiteral((int)value,text);returnCreateLiteral(value,text);}}ExpressionParseRealLiteral(){ValidateToken(TokenId.RealLiteral);stringtext=token.text;objectvalue=null;charlast=text[text.Length-1];if(last=='F'||last=='f'){floatf;if(Single.TryParse(text.Substring(0,text.Length-1),outf))value=f;}else{doubled;if(Double.TryParse(text,outd))value=d;}if(value==null)throwParseError(Res.InvalidRealLiteral,text);NextToken();returnCreateLiteral(value,text);}ExpressionCreateLiteral(objectvalue,stringtext){ConstantExpressionexpr=Expression.Constant(value);literals.Add(expr,text);returnexpr;}ExpressionParseParenExpression(){ValidateToken(TokenId.OpenParen,Res.OpenParenExpected);NextToken();Expressione=ParseExpression();ValidateToken(TokenId.CloseParen,Res.CloseParenOrOperatorExpected);NextToken();returne;}ExpressionParseIdentifier(){ValidateToken(TokenId.Identifier);objectvalue;if(keywords.TryGetValue(token.text,outvalue)){if(valueisType)returnParseTypeAccess((Type)value);if(value==(object)keywordIt)returnParseIt();if(value==(object)keywordIif)returnParseIif();if(value==(object)keywordNew)returnParseNew();NextToken();return(Expression)value;}if(symbols.TryGetValue(token.text,outvalue)||externals!=null&&externals.TryGetValue(token.text,outvalue)){Expressionexpr=valueasExpression;if(expr==null){expr=Expression.Constant(value);}else{LambdaExpressionlambda=exprasLambdaExpression;if(lambda!=null)returnParseLambdaInvocation(lambda);}NextToken();returnexpr;}if(it!=null)returnParseMemberAccess(null,it);throwParseError(Res.UnknownIdentifier,token.text);}ExpressionParseIt(){if(it==null)throwParseError(Res.NoItInScope);NextToken();returnit;}ExpressionParseIif(){interrorPos=token.pos;NextToken();Expression[]args=ParseArgumentList();if(args.Length!=3)throwParseError(errorPos,Res.IifRequiresThreeArgs);returnGenerateConditional(args[0],args[1],args[2],errorPos);}ExpressionGenerateConditional(Expressiontest,Expressionexpr1,Expressionexpr2,interrorPos){if(test.Type!=typeof(bool))throwParseError(errorPos,Res.FirstExprMustBeBool);if(expr1.Type!=expr2.Type){Expressionexpr1as2=expr2!=nullLiteral?PromoteExpression(expr1,expr2.Type,true):null;Expressionexpr2as1=expr1!=nullLiteral?PromoteExpression(expr2,expr1.Type,true):null;if(expr1as2!=null&&expr2as1==null){expr1=expr1as2;}elseif(expr2as1!=null&&expr1as2==null){expr2=expr2as1;}else{stringtype1=expr1!=nullLiteral?expr1.Type.Name:"null";stringtype2=expr2!=nullLiteral?expr2.Type.Name:"null";if(expr1as2!=null&&expr2as1!=null)throwParseError(errorPos,Res.BothTypesConvertToOther,type1,type2);throwParseError(errorPos,Res.NeitherTypeConvertsToOther,type1,type2);}}returnExpression.Condition(test,expr1,expr2);}ExpressionParseNew(){NextToken();ValidateToken(TokenId.OpenParen,Res.OpenParenExpected);NextToken();List<DynamicProperty>properties=newList<DynamicProperty>();List<Expression>expressions=newList<Expression>();while(true){intexprPos=token.pos;Expressionexpr=ParseExpression();stringpropName;if(TokenIdentifierIs("as")){NextToken();propName=GetIdentifier();NextToken();}else{MemberExpressionme=exprasMemberExpression;if(me==null)throwParseError(exprPos,Res.MissingAsClause);propName=me.Member.Name;}expressions.Add(expr);properties.Add(newDynamicProperty(propName,expr.Type));if(token.id!=TokenId.Comma)break;NextToken();}ValidateToken(TokenId.CloseParen,Res.CloseParenOrCommaExpected);NextToken();Typetype=DynamicExpression.CreateClass(properties);MemberBinding[]bindings=newMemberBinding[properties.Count];for(inti=0;i<bindings.Length;i++)bindings[i]=Expression.Bind(type.GetProperty(properties[i].Name),expressions[i]);returnExpression.MemberInit(Expression.New(type),bindings);}ExpressionParseLambdaInvocation(LambdaExpressionlambda){interrorPos=token.pos;NextToken();Expression[]args=ParseArgumentList();MethodBasemethod;if(FindMethod(lambda.Type,"Invoke",false,args,outmethod)!=1)throwParseError(errorPos,Res.ArgsIncompatibleWithLambda);returnExpression.Invoke(lambda,args);}ExpressionParseTypeAccess(Typetype){interrorPos=token.pos;NextToken();if(token.id==TokenId.Question){if(!type.IsValueType||IsNullableType(type))throwParseError(errorPos,Res.TypeHasNoNullableForm,GetTypeName(type));type=typeof(Nullable<>).MakeGenericType(type);NextToken();}if(token.id==TokenId.OpenParen){Expression[]args=ParseArgumentList();MethodBasemethod;switch(FindBestMethod(type.GetConstructors(),args,outmethod)){case0:if(args.Length==1)returnGenerateConversion(args[0],type,errorPos);throwParseError(errorPos,Res.NoMatchingConstructor,GetTypeName(type));case1:returnExpression.New((ConstructorInfo)method,args);default:throwParseError(errorPos,Res.AmbiguousConstructorInvocation,GetTypeName(type));}}ValidateToken(TokenId.Dot,Res.DotOrOpenParenExpected);NextToken();returnParseMemberAccess(type,null);}ExpressionGenerateConversion(Expressionexpr,Typetype,interrorPos){TypeexprType=expr.Type;if(exprType==type)returnexpr;if(exprType.IsValueType&&type.IsValueType){if((IsNullableType(exprType)||IsNullableType(type))&&GetNonNullableType(exprType)==GetNonNullableType(type))returnExpression.Convert(expr,type);if((IsNumericType(exprType)||IsEnumType(exprType))&&(IsNumericType(type))||IsEnumType(type))returnExpression.ConvertChecked(expr,type);}if(exprType.IsAssignableFrom(type)||type.IsAssignableFrom(exprType)||exprType.IsInterface||type.IsInterface)returnExpression.Convert(expr,type);throwParseError(errorPos,Res.CannotConvertValue,GetTypeName(exprType),GetTypeName(type));}ExpressionParseMemberAccess(Typetype,Expressioninstance){if(instance!=null)type=instance.Type;interrorPos=token.pos;stringid=GetIdentifier();NextToken();if(token.id==TokenId.OpenParen){if(instance!=null&&type!=typeof(string)){TypeenumerableType=FindGenericType(typeof(IEnumerable<>),type);if(enumerableType!=null){TypeelementType=enumerableType.GetGenericArguments()[0];returnParseAggregate(instance,elementType,id,errorPos);}}Expression[]args=ParseArgumentList();MethodBasemb;switch(FindMethod(type,id,instance==null,args,outmb)){case0:throwParseError(errorPos,Res.NoApplicableMethod,id,GetTypeName(type));case1:MethodInfomethod=(MethodInfo)mb;if(!IsPredefinedType(method.DeclaringType))throwParseError(errorPos,Res.MethodsAreInaccessible,GetTypeName(method.DeclaringType));if(method.ReturnType==typeof(void))throwParseError(errorPos,Res.MethodIsVoid,id,GetTypeName(method.DeclaringType));returnExpression.Call(instance,(MethodInfo)method,args);default:throwParseError(errorPos,Res.AmbiguousMethodInvocation,id,GetTypeName(type));}}else{MemberInfomember=FindPropertyOrField(type,id,instance==null);if(member==null)throwParseError(errorPos,Res.UnknownPropertyOrField,id,GetTypeName(type));returnmemberisPropertyInfo?Expression.Property(instance,(PropertyInfo)member):Expression.Field(instance,(FieldInfo)member);}}staticTypeFindGenericType(Typegeneric,Typetype){while(type!=null&&type!=typeof(object)){if(type.IsGenericType&&type.GetGenericTypeDefinition()==generic)returntype;if(generic.IsInterface){foreach(TypeintfTypeintype.GetInterfaces()){Typefound=FindGenericType(generic,intfType);if(found!=null)returnfound;}}type=type.BaseType;}returnnull;}ExpressionParseAggregate(Expressioninstance,TypeelementType,stringmethodName,interrorPos){ParameterExpressionouterIt=it;ParameterExpressioninnerIt=Expression.Parameter(elementType,"");it=innerIt;Expression[]args=ParseArgumentList();it=outerIt;MethodBasesignature;if(FindMethod(typeof(IEnumerableSignatures),methodName,false,args,outsignature)!=1)throwParseError(errorPos,Res.NoApplicableAggregate,methodName);Type[]typeArgs;if(signature.Name=="Min"||signature.Name=="Max"){typeArgs=newType[]{elementType,args[0].Type};}else{typeArgs=newType[]{elementType};}if(args.Length==0){args=newExpression[]{instance};}else{args=newExpression[]{instance,Expression.Lambda(args[0],innerIt)};}returnExpression.Call(typeof(Enumerable),signature.Name,typeArgs,args);}Expression[]ParseArgumentList(){ValidateToken(TokenId.OpenParen,Res.OpenParenExpected);NextToken();Expression[]args=token.id!=TokenId.CloseParen?ParseArguments():newExpression[0];ValidateToken(TokenId.CloseParen,Res.CloseParenOrCommaExpected);NextToken();returnargs;}Expression[]ParseArguments(){List<Expression>argList=newList<Expression>();while(true){argList.Add(ParseExpression());if(token.id!=TokenId.Comma)break;NextToken();}returnargList.ToArray();}ExpressionParseElementAccess(Expressionexpr){interrorPos=token.pos;ValidateToken(TokenId.OpenBracket,Res.OpenParenExpected);NextToken();Expression[]args=ParseArguments();ValidateToken(TokenId.CloseBracket,Res.CloseBracketOrCommaExpected);NextToken();if(expr.Type.IsArray){if(expr.Type.GetArrayRank()!=1||args.Length!=1)throwParseError(errorPos,Res.CannotIndexMultiDimArray);Expressionindex=PromoteExpression(args[0],typeof(int),true);if(index==null)throwParseError(errorPos,Res.InvalidIndex);returnExpression.ArrayIndex(expr,index);}else{MethodBasemb;switch(FindIndexer(expr.Type,args,outmb)){case0:throwParseError(errorPos,Res.NoApplicableIndexer,GetTypeName(expr.Type));case1:returnExpression.Call(expr,(MethodInfo)mb,args);default:throwParseError(errorPos,Res.AmbiguousIndexerInvocation,GetTypeName(expr.Type));}}}staticboolIsPredefinedType(Typetype){foreach(TypetinpredefinedTypes)if(t==type)returntrue;returnfalse;}staticboolIsNullableType(Typetype){returntype.IsGenericType&&type.GetGenericTypeDefinition()==typeof(Nullable<>);}staticTypeGetNonNullableType(Typetype){returnIsNullableType(type)?type.GetGenericArguments()[0]:type;}staticstringGetTypeName(Typetype){TypebaseType=GetNonNullableType(type);strings=baseType.Name;if(type!=baseType)s+='?';returns;}staticboolIsNumericType(Typetype){returnGetNumericTypeKind(type)!=0;}staticboolIsSignedIntegralType(Typetype){returnGetNumericTypeKind(type)==2;}staticboolIsUnsignedIntegralType(Typetype){returnGetNumericTypeKind(type)==3;}staticintGetNumericTypeKind(Typetype){type=GetNonNullableType(type);if(type.IsEnum)return0;switch(Type.GetTypeCode(type)){caseTypeCode.Char:caseTypeCode.Single:caseTypeCode.Double:caseTypeCode.Decimal:return1;caseTypeCode.SByte:caseTypeCode.Int16:caseTypeCode.Int32:caseTypeCode.Int64:return2;caseTypeCode.Byte:caseTypeCode.UInt16:caseTypeCode.UInt32:caseTypeCode.UInt64:return3;default:return0;}}staticboolIsEnumType(Typetype){returnGetNonNullableType(type).IsEnum;}voidCheckAndPromoteOperand(Typesignatures,stringopName,refExpressionexpr,interrorPos){Expression[]args=newExpression[]{expr};MethodBasemethod;if(FindMethod(signatures,"F",false,args,outmethod)!=1)throwParseError(errorPos,Res.IncompatibleOperand,opName,GetTypeName(args[0].Type));expr=args[0];}voidCheckAndPromoteOperands(Typesignatures,stringopName,refExpressionleft,refExpressionright,interrorPos){Expression[]args=newExpression[]{left,right};MethodBasemethod;if(FindMethod(signatures,"F",false,args,outmethod)!=1)throwIncompatibleOperandsError(opName,left,right,errorPos);left=args[0];right=args[1];}ExceptionIncompatibleOperandsError(stringopName,Expressionleft,Expressionright,intpos){returnParseError(pos,Res.IncompatibleOperands,opName,GetTypeName(left.Type),GetTypeName(right.Type));}MemberInfoFindPropertyOrField(Typetype,stringmemberName,boolstaticAccess){BindingFlagsflags=BindingFlags.Public|BindingFlags.DeclaredOnly|(staticAccess?BindingFlags.Static:BindingFlags.Instance);foreach(TypetinSelfAndBaseTypes(type)){MemberInfo[]members=t.FindMembers(MemberTypes.Property|MemberTypes.Field,flags,Type.FilterNameIgnoreCase,memberName);if(members.Length!=0)returnmembers[0];}returnnull;}intFindMethod(Typetype,stringmethodName,boolstaticAccess,Expression[]args,outMethodBasemethod){BindingFlagsflags=BindingFlags.Public|BindingFlags.DeclaredOnly|(staticAccess?BindingFlags.Static:BindingFlags.Instance);foreach(TypetinSelfAndBaseTypes(type)){MemberInfo[]members=t.FindMembers(MemberTypes.Method,flags,Type.FilterNameIgnoreCase,methodName);intcount=FindBestMethod(members.Cast<MethodBase>(),args,outmethod);if(count!=0)returncount;}method=null;return0;}intFindIndexer(Typetype,Expression[]args,outMethodBasemethod){foreach(TypetinSelfAndBaseTypes(type)){MemberInfo[]members=t.GetDefaultMembers();if(members.Length!=0){IEnumerable<MethodBase>methods=members.OfType<PropertyInfo>().Select(p=>(MethodBase)p.GetGetMethod()).Where(m=>m!=null);intcount=FindBestMethod(methods,args,outmethod);if(count!=0)returncount;}}method=null;return0;}staticIEnumerable<Type>SelfAndBaseTypes(Typetype){if(type.IsInterface){List<Type>types=newList<Type>();AddInterface(types,type);returntypes;}returnSelfAndBaseClasses(type);}staticIEnumerable<Type>SelfAndBaseClasses(Typetype){while(type!=null){yieldreturntype;type=type.BaseType;}}staticvoidAddInterface(List<Type>types,Typetype){if(!types.Contains(type)){types.Add(type);foreach(Typetintype.GetInterfaces())AddInterface(types,t);}}classMethodData{publicMethodBaseMethodBase;publicParameterInfo[]Parameters;publicExpression[]Args;}intFindBestMethod(IEnumerable<MethodBase>methods,Expression[]args,outMethodBasemethod){MethodData[]applicable=methods.Select(m=>newMethodData{MethodBase=m,Parameters=m.GetParameters()}).Where(m=>IsApplicable(m,args)).ToArray();if(applicable.Length>1){applicable=applicable.Where(m=>applicable.All(n=>m==n||IsBetterThan(args,m,n))).ToArray();}if(applicable.Length==1){MethodDatamd=applicable[0];for(inti=0;i<args.Length;i++)args[i]=md.Args[i];method=md.MethodBase;}else{method=null;}returnapplicable.Length;}boolIsApplicable(MethodDatamethod,Expression[]args){if(method.Parameters.Length!=args.Length)returnfalse;Expression[]promotedArgs=newExpression[args.Length];for(inti=0;i<args.Length;i++){ParameterInfopi=method.Parameters[i];if(pi.IsOut)returnfalse;Expressionpromoted=PromoteExpression(args[i],pi.ParameterType,false);if(promoted==null)returnfalse;promotedArgs[i]=promoted;}method.Args=promotedArgs;returntrue;}ExpressionPromoteExpression(Expressionexpr,Typetype,boolexact){if(expr.Type==type)returnexpr;if(exprisConstantExpression){ConstantExpressionce=(ConstantExpression)expr;if(ce==nullLiteral){if(!type.IsValueType||IsNullableType(type))returnExpression.Constant(null,type);}else{stringtext;if(literals.TryGetValue(ce,outtext)){Typetarget=GetNonNullableType(type);Objectvalue=null;switch(Type.GetTypeCode(ce.Type)){caseTypeCode.Int32:caseTypeCode.UInt32:caseTypeCode.Int64:caseTypeCode.UInt64:value=ParseNumber(text,target);break;caseTypeCode.Double:if(target==typeof(decimal))value=ParseNumber(text,target);break;caseTypeCode.String:value=ParseEnum(text,target);break;}if(value!=null)returnExpression.Constant(value,type);}}}if(IsCompatibleWith(expr.Type,type)){if(type.IsValueType||exact)returnExpression.Convert(expr,type);returnexpr;}returnnull;}staticobjectParseNumber(stringtext,Typetype){switch(Type.GetTypeCode(GetNonNullableType(type))){caseTypeCode.SByte:sbytesb;if(sbyte.TryParse(text,outsb))returnsb;break;caseTypeCode.Byte:byteb;if(byte.TryParse(text,outb))returnb;break;caseTypeCode.Int16:shorts;if(short.TryParse(text,outs))returns;break;caseTypeCode.UInt16:ushortus;if(ushort.TryParse(text,outus))returnus;break;caseTypeCode.Int32:inti;if(int.TryParse(text,outi))returni;break;caseTypeCode.UInt32:uintui;if(uint.TryParse(text,outui))returnui;break;caseTypeCode.Int64:longl;if(long.TryParse(text,outl))returnl;break;caseTypeCode.UInt64:ulongul;if(ulong.TryParse(text,outul))returnul;break;caseTypeCode.Single:floatf;if(float.TryParse(text,outf))returnf;break;caseTypeCode.Double:doubled;if(double.TryParse(text,outd))returnd;break;caseTypeCode.Decimal:decimale;if(decimal.TryParse(text,oute))returne;break;}returnnull;}staticobjectParseEnum(stringname,Typetype){if(type.IsEnum){MemberInfo[]memberInfos=type.FindMembers(MemberTypes.Field,BindingFlags.Public|BindingFlags.DeclaredOnly|BindingFlags.Static,Type.FilterNameIgnoreCase,name);if(memberInfos.Length!=0)return((FieldInfo)memberInfos[0]).GetValue(null);}returnnull;}staticboolIsCompatibleWith(Typesource,Typetarget){if(source==target)returntrue;if(!target.IsValueType)returntarget.IsAssignableFrom(source);Typest=GetNonNullableType(source);Typett=GetNonNullableType(target);if(st!=source&&tt==target)returnfalse;TypeCodesc=st.IsEnum?TypeCode.Object:Type.GetTypeCode(st);TypeCodetc=tt.IsEnum?TypeCode.Object:Type.GetTypeCode(tt);switch(sc){caseTypeCode.SByte:switch(tc){caseTypeCode.SByte:caseTypeCode.Int16:caseTypeCode.Int32:caseTypeCode.Int64:caseTypeCode.Single:caseTypeCode.Double:caseTypeCode.Decimal:returntrue;}break;caseTypeCode.Byte:switch(tc){caseTypeCode.Byte:caseTypeCode.Int16:caseTypeCode.UInt16:caseTypeCode.Int32:caseTypeCode.UInt32:caseTypeCode.Int64:caseTypeCode.UInt64:caseTypeCode.Single:caseTypeCode.Double:caseTypeCode.Decimal:returntrue;}break;caseTypeCode.Int16:switch(tc){caseTypeCode.Int16:caseTypeCode.Int32:caseTypeCode.Int64:caseTypeCode.Single:caseTypeCode.Double:caseTypeCode.Decimal:returntrue;}break;caseTypeCode.UInt16:switch(tc){caseTypeCode.UInt16:caseTypeCode.Int32:caseTypeCode.UInt32:caseTypeCode.Int64:caseTypeCode.UInt64:caseTypeCode.Single:caseTypeCode.Double:caseTypeCode.Decimal:returntrue;}break;caseTypeCode.Int32:switch(tc){caseTypeCode.Int32:caseTypeCode.Int64:caseTypeCode.Single:caseTypeCode.Double:caseTypeCode.Decimal:returntrue;}break;caseTypeCode.UInt32:switch(tc){caseTypeCode.UInt32:caseTypeCode.Int64:caseTypeCode.UInt64:caseTypeCode.Single:caseTypeCode.Double:caseTypeCode.Decimal:returntrue;}break;caseTypeCode.Int64:switch(tc){caseTypeCode.Int64:caseTypeCode.Single:caseTypeCode.Double:caseTypeCode.Decimal:returntrue;}break;caseTypeCode.UInt64:switch(tc){caseTypeCode.UInt64:caseTypeCode.Single:caseTypeCode.Double:caseTypeCode.Decimal:returntrue;}break;caseTypeCode.Single:switch(tc){caseTypeCode.Single:caseTypeCode.Double:returntrue;}break;default:if(st==tt)returntrue;break;}returnfalse;}staticboolIsBetterThan(Expression[]args,MethodDatam1,MethodDatam2){boolbetter=false;for(inti=0;i<args.Length;i++){intc=CompareConversions(args[i].Type,m1.Parameters[i].ParameterType,m2.Parameters[i].ParameterType);if(c<0)returnfalse;if(c>0)better=true;}returnbetter;}//Return1ifs->t1isabetterconversionthans->t2//Return-1ifs->t2isabetterconversionthans->t1//Return0ifneitherconversionisbetterstaticintCompareConversions(Types,Typet1,Typet2){if(t1==t2)return0;if(s==t1)return1;if(s==t2)return-1;boolt1t2=IsCompatibleWith(t1,t2);boolt2t1=IsCompatibleWith(t2,t1);if(t1t2&&!t2t1)return1;if(t2t1&&!t1t2)return-1;if(IsSignedIntegralType(t1)&&IsUnsignedIntegralType(t2))return1;if(IsSignedIntegralType(t2)&&IsUnsignedIntegralType(t1))return-1;return0;}ExpressionGenerateEqual(Expressionleft,Expressionright){returnExpression.Equal(left,right);}ExpressionGenerateNotEqual(Expressionleft,Expressionright){returnExpression.NotEqual(left,right);}ExpressionGenerateGreaterThan(Expressionleft,Expressionright){if(left.Type==typeof(string)){returnExpression.GreaterThan(GenerateStaticMethodCall("Compare",left,right),Expression.Constant(0));}returnExpression.GreaterThan(left,right);}ExpressionGenerateGreaterThanEqual(Expressionleft,Expressionright){if(left.Type==typeof(string)){returnExpression.GreaterThanOrEqual(GenerateStaticMethodCall("Compare",left,right),Expression.Constant(0));}returnExpression.GreaterThanOrEqual(left,right);}ExpressionGenerateLessThan(Expressionleft,Expressionright){if(left.Type==typeof(string)){returnExpression.LessThan(GenerateStaticMethodCall("Compare",left,right),Expression.Constant(0));}returnExpression.LessThan(left,right);}ExpressionGenerateLessThanEqual(Expressionleft,Expressionright){if(left.Type==typeof(string)){returnExpression.LessThanOrEqual(GenerateStaticMethodCall("Compare",left,right),Expression.Constant(0));}returnExpression.LessThanOrEqual(left,right);}ExpressionGenerateAdd(Expressionleft,Expressionright){if(left.Type==typeof(string)&&right.Type==typeof(string)){returnGenerateStaticMethodCall("Concat",left,right);}returnExpression.Add(left,right);}ExpressionGenerateSubtract(Expressionleft,Expressionright){returnExpression.Subtract(left,right);}ExpressionGenerateStringConcat(Expressionleft,Expressionright){returnExpression.Call(null,typeof(string).GetMethod("Concat",new[]{typeof(object),typeof(object)}),new[]{left,right});}MethodInfoGetStaticMethod(stringmethodName,Expressionleft,Expressionright){returnleft.Type.GetMethod(methodName,new[]{left.Type,right.Type});}ExpressionGenerateStaticMethodCall(stringmethodName,Expressionleft,Expressionright){returnExpression.Call(null,GetStaticMethod(methodName,left,right),new[]{left,right});}voidSetTextPos(intpos){textPos=pos;ch=textPos<textLen?text[textPos]:'\0';}voidNextChar(){if(textPos<textLen)textPos++;ch=textPos<textLen?text[textPos]:'\0';}voidNextToken(){while(Char.IsWhiteSpace(ch))NextChar();TokenIdt;inttokenPos=textPos;switch(ch){case'!':NextChar();if(ch=='='){NextChar();t=TokenId.ExclamationEqual;}else{t=TokenId.Exclamation;}break;case'%':NextChar();t=TokenId.Percent;break;case'&':NextChar();if(ch=='&'){NextChar();t=TokenId.DoubleAmphersand;}else{t=TokenId.Amphersand;}break;case'(':NextChar();t=TokenId.OpenParen;break;case')':NextChar();t=TokenId.CloseParen;break;case'*':NextChar();t=TokenId.Asterisk;break;case'+':NextChar();t=TokenId.Plus;break;case',':NextChar();t=TokenId.Comma;break;case'-':NextChar();t=TokenId.Minus;break;case'.':NextChar();t=TokenId.Dot;break;case'/':NextChar();t=TokenId.Slash;break;case':':NextChar();t=TokenId.Colon;break;case'<':NextChar();if(ch=='='){NextChar();t=TokenId.LessThanEqual;}elseif(ch=='>'){NextChar();t=TokenId.LessGreater;}else{t=TokenId.LessThan;}break;case'=':NextChar();if(ch=='='){NextChar();t=TokenId.DoubleEqual;}else{t=TokenId.Equal;}break;case'>':NextChar();if(ch=='='){NextChar();t=TokenId.GreaterThanEqual;}else{t=TokenId.GreaterThan;}break;case'?':NextChar();t=TokenId.Question;break;case'[':NextChar();t=TokenId.OpenBracket;break;case']':NextChar();t=TokenId.CloseBracket;break;case'|':NextChar();if(ch=='|'){NextChar();t=TokenId.DoubleBar;}else{t=TokenId.Bar;}break;case'"':case'\'':charquote=ch;do{NextChar();while(textPos<textLen&&ch!=quote)NextChar();if(textPos==textLen)throwParseError(textPos,Res.UnterminatedStringLiteral);NextChar();}while(ch==quote);t=TokenId.StringLiteral;break;default:if(Char.IsLetter(ch)||ch=='@'||ch=='_'){do{NextChar();}while(Char.IsLetterOrDigit(ch)||ch=='_');t=TokenId.Identifier;break;}if(Char.IsDigit(ch)){t=TokenId.IntegerLiteral;do{NextChar();}while(Char.IsDigit(ch));if(ch=='.'){t=TokenId.RealLiteral;NextChar();ValidateDigit();do{NextChar();}while(Char.IsDigit(ch));}if(ch=='E'||ch=='e'){t=TokenId.RealLiteral;NextChar();if(ch=='+'||ch=='-')NextChar();ValidateDigit();do{NextChar();}while(Char.IsDigit(ch));}if(ch=='F'||ch=='f')NextChar();break;}if(textPos==textLen){t=TokenId.End;break;}throwParseError(textPos,Res.InvalidCharacter,ch);}token.id=t;token.text=text.Substring(tokenPos,textPos-tokenPos);token.pos=tokenPos;}boolTokenIdentifierIs(stringid){returntoken.id==TokenId.Identifier&&String.Equals(id,token.text,StringComparison.OrdinalIgnoreCase);}stringGetIdentifier(){ValidateToken(TokenId.Identifier,Res.IdentifierExpected);stringid=token.text;if(id.Length>1&&id[0]=='@')id=id.Substring(1);returnid;}voidValidateDigit(){if(!Char.IsDigit(ch))throwParseError(textPos,Res.DigitExpected);}voidValidateToken(TokenIdt,stringerrorMessage){if(token.id!=t)throwParseError(errorMessage);}voidValidateToken(TokenIdt){if(token.id!=t)throwParseError(Res.SyntaxError);}ExceptionParseError(stringformat,paramsobject[]args){returnParseError(token.pos,format,args);}ExceptionParseError(intpos,stringformat,paramsobject[]args){returnnewParseException(string.Format(System.Globalization.CultureInfo.CurrentCulture,format,args),pos);}staticDictionary<string,object>CreateKeywords(){Dictionary<string,object>d=newDictionary<string,object>(StringComparer.OrdinalIgnoreCase);d.Add("true",trueLiteral);d.Add("false",falseLiteral);d.Add("null",nullLiteral);d.Add(keywordIt,keywordIt);d.Add(keywordIif,keywordIif);d.Add(keywordNew,keywordNew);foreach(TypetypeinpredefinedTypes)d.Add(type.Name,type);returnd;}}staticclassRes{publicconststringDuplicateIdentifier="The identifier '{0}' was defined more than once";publicconststringExpressionTypeMismatch="Expression of type '{0}' expected";publicconststringExpressionExpected="Expression expected";publicconststringInvalidCharacterLiteral="Character literal must contain exactly one character";publicconststringInvalidIntegerLiteral="Invalid integer literal '{0}'";publicconststringInvalidRealLiteral="Invalid real literal '{0}'";publicconststringUnknownIdentifier="Unknown identifier '{0}'";publicconststringNoItInScope="No 'it' is in scope";publicconststringIifRequiresThreeArgs="The 'iif' function requires three arguments";publicconststringFirstExprMustBeBool="The first expression must be of type 'Boolean'";publicconststringBothTypesConvertToOther="Both of the types '{0}' and '{1}' convert to the other";publicconststringNeitherTypeConvertsToOther="Neither of the types '{0}' and '{1}' converts to the other";publicconststringMissingAsClause="Expression is missing an 'as' clause";publicconststringArgsIncompatibleWithLambda="Argument list incompatible with lambda expression";publicconststringTypeHasNoNullableForm="Type '{0}' has no nullable form";publicconststringNoMatchingConstructor="No matching constructor in type '{0}'";publicconststringAmbiguousConstructorInvocation="Ambiguous invocation of '{0}' constructor";publicconststringCannotConvertValue="A value of type '{0}' cannot be converted to type '{1}'";publicconststringNoApplicableMethod="No applicable method '{0}' exists in type '{1}'";publicconststringMethodsAreInaccessible="Methods on type '{0}' are not accessible";publicconststringMethodIsVoid="Method '{0}' in type '{1}' does not return a value";publicconststringAmbiguousMethodInvocation="Ambiguous invocation of method '{0}' in type '{1}'";publicconststringUnknownPropertyOrField="No property or field '{0}' exists in type '{1}'";publicconststringNoApplicableAggregate="No applicable aggregate method '{0}' exists";publicconststringCannotIndexMultiDimArray="Indexing of multi-dimensional arrays is not supported";publicconststringInvalidIndex="Array index must be an integer expression";publicconststringNoApplicableIndexer="No applicable indexer exists in type '{0}'";publicconststringAmbiguousIndexerInvocation="Ambiguous invocation of indexer in type '{0}'";publicconststringIncompatibleOperand="Operator '{0}' incompatible with operand type '{1}'";publicconststringIncompatibleOperands="Operator '{0}' incompatible with operand types '{1}' and '{2}'";publicconststringUnterminatedStringLiteral="Unterminated string literal";publicconststringInvalidCharacter="Syntax error '{0}'";publicconststringDigitExpected="Digit expected";publicconststringSyntaxError="Syntax error";publicconststringTokenExpected="{0} expected";publicconststringParseExceptionFormat="{0} (at index {1})";publicconststringColonExpected="':' expected";publicconststringOpenParenExpected="'(' expected";publicconststringCloseParenOrOperatorExpected="')' or operator expected";publicconststringCloseParenOrCommaExpected="')' or ',' expected";publicconststringDotOrOpenParenExpected="'.' or '(' expected";publicconststringOpenBracketExpected="'[' expected";publicconststringCloseBracketOrCommaExpected="']' or ',' expected";publicconststringIdentifierExpected="Identifier expected";}}