private static DLR.Expression BuildMonadicCase( Token functionToken, DLR.LabelTarget methodReturnTarget, DLR.ParameterExpression methodEnvArg, DLR.ParameterExpression methodRightArg) { DLR.Expression result; AbstractMonadicFunction monadic = MethodChooser.GetMonadicMethod(functionToken); if (monadic != null) { result = DLR.Expression.Goto( methodReturnTarget, DLR.Expression.Call( DLR.Expression.Constant(monadic), monadic.GetType().GetMethod("Execute"), methodRightArg, methodEnvArg ) ); } 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 GenerateMonadic(AplusScope scope, DLR.Expression argument) { DLR.Expression result; // Handle the result monadic function a little differently: if (this.token.Type == Tokens.RESULT) { result = scope.ReturnTarget != null // If inside of a function create a return expression Tree ? DLR.Expression.Return(scope.ReturnTarget, argument, typeof(AType)) // Otherwise just return the value : argument ; } else { AbstractMonadicFunction method = MethodChooser.GetMonadicMethod(this.token); if (method == null) { throw new ParseException(String.Format("Not supported Monadic function[{0}]", this.token)); } result = DLR.Expression.Call( DLR.Expression.Constant(method), method.GetType().GetMethod("Execute"), argument, scope.GetRuntimeExpression() ); } return(result); }
/// <summary> /// Initializes a new instance of <see cref="DyadicFunction"/> AST node. /// </summary> /// <param name="token">The <see cref="Token"/> to use for the dyadic function.</param> /// <param name="leftExpression">The left hand argument of the dyadic function.</param> /// <param name="rightExpression">The right hand argument of the dyadic function.</param> public DyadicFunction(Token token, Node leftExpression, Node rightExpression) { this.token = token; this.leftExpression = leftExpression; this.rightExpression = rightExpression; MethodChooser.ConvertToDyadicToken(this.token); }
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); }