Пример #1
0
        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);
        }
Пример #2
0
        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);
        }