private static DLR.Expression BuildDyadicCase( Token functionToken, DLR.LabelTarget returnTarget, DLR.Expression environment, DLR.Expression rightParam, DLR.Expression leftParam) { DLR.Expression result; MethodInfo method = typeof(AbstractDyadicFunction).GetMethod("Execute"); if (functionToken.Type == Tokens.TYPE) { result = DLR.Expression.IfThenElse( // $left.IsNumber || ($left.Type == ATypes.ANull) DLR.Expression.OrElse( DLR.Expression.IsTrue( DLR.Expression.PropertyOrField(leftParam, "IsNumber") ), DLR.Expression.Equal( DLR.Expression.PropertyOrField(leftParam, "Type"), DLR.Expression.Constant(ATypes.ANull) ) ), // Or($right, $left) DLR.Expression.Goto( returnTarget, DLR.Expression.Call( DLR.Expression.Constant(DyadicFunctionInstance.Or), method, rightParam, leftParam, environment ) ), // Cast($right, $left) DLR.Expression.Goto( returnTarget, DLR.Expression.Call( DLR.Expression.Constant(DyadicFunctionInstance.Cast), method, rightParam, leftParam, environment ) ) ); } else { MethodChooser.ConvertToDyadicToken(functionToken); AbstractDyadicFunction dyadic = MethodChooser.GetDyadicMethod(functionToken); if (dyadic != null) { result = DLR.Expression.Goto( returnTarget, DLR.Expression.Call( DLR.Expression.Constant(dyadic), method, rightParam, leftParam, environment ) ); } else { result = DLR.Expression.Throw( DLR.Expression.New( typeof(Error.Valence).GetConstructor(new Type[] { typeof(string) }), DLR.Expression.Constant(functionToken.Text) ) ); } } return(result); }
private DLR.Expression GenerateDyadic(AplusScope scope, DLR.Expression right, DLR.Expression left) { DLR.Expression result; DLR.ParameterExpression environment = scope.GetRuntimeExpression(); if (this.token.Type == Tokens.OR) { DLR.ParameterExpression leftParam = DLR.Expression.Variable(typeof(AType), "$$leftParam"); DLR.ParameterExpression rightParam = DLR.Expression.Variable(typeof(AType), "$$rightParam"); DLR.ParameterExpression valueParam = DLR.Expression.Variable(typeof(AType), "$$valueParam"); result = DLR.Expression.Block( new DLR.ParameterExpression[] { leftParam, rightParam, valueParam }, DLR.Expression.Assign(rightParam, right), DLR.Expression.Assign(leftParam, left), DLR.Expression.IfThenElse( // $left.IsNumber || ($left.Type == ATypes.ANull) DLR.Expression.OrElse( DLR.Expression.IsTrue( DLR.Expression.PropertyOrField(leftParam, "IsNumber") ), DLR.Expression.Equal( DLR.Expression.PropertyOrField(leftParam, "Type"), DLR.Expression.Constant(ATypes.ANull) ) ), // Or($right, $left) DLR.Expression.Assign( valueParam, DLR.Expression.Call( DLR.Expression.Constant(DyadicFunctionInstance.Or), DyadicFunctionInstance.Or.GetType().GetMethod("Execute"), rightParam, leftParam, environment ) ), // Cast($right, $left) DLR.Expression.Assign( valueParam, DLR.Expression.Call( DLR.Expression.Constant(DyadicFunctionInstance.Cast), DyadicFunctionInstance.Cast.GetType().GetMethod("Execute"), rightParam, leftParam, environment ) ) ), valueParam ); } else if (this.token.Type == Tokens.BWOR) { DLR.ParameterExpression rightParam = DLR.Expression.Variable(typeof(AType), "$$rightParam"); DLR.ParameterExpression leftParam = DLR.Expression.Variable(typeof(AType), "$$leftParam"); result = DLR.Expression.Block( new DLR.ParameterExpression[] { leftParam, rightParam }, DLR.Expression.Assign(rightParam, right), DLR.Expression.Assign(leftParam, left), DLR.Expression.Condition( // $left.Type == ATypes.ASymbol DLR.Expression.Equal( leftParam.Property("Type"), DLR.Expression.Constant(ATypes.ASymbol) ), DLR.Expression.Constant(DyadicFunctionInstance.BitwiseCast).Call <BitwiseCast>( "Execute", rightParam, leftParam, environment ), DLR.Expression.Constant(DyadicFunctionInstance.BitwiseOr).Call <BitwiseOr>( "Execute", rightParam, leftParam, environment ) ) ); } else { AbstractDyadicFunction method = MethodChooser.GetDyadicMethod(this.token); if (method == null) { throw new ParseException(String.Format("Not supported Dyadic function[{0}]", this.token)); } result = DLR.Expression.Call( DLR.Expression.Constant(method), method.GetType().GetMethod("Execute"), right, left, environment ); } return(result); }