Beispiel #1
0
 public Expression<Func<double, double>> CreateFunction(Node root, CompileResult status)
 {
     Status = status;
     ParameterExpression parameter = Expression.Parameter(typeof(double), "x");
     Binder.RegisterParameter(parameter);
     Expression body = CreateExpressionCore(root);
     if (body == null)
     {
         return null;
     }
     var expressionTree = Expression.Lambda<Func<double, double>>(body, parameter);
     return expressionTree;
 }
Beispiel #2
0
 public Expression<Func<double>> CreateExpression(Node root, CompileResult status)
 {
     Status = status;
     Expression body = CreateExpressionCore(root);
     if (body == null)
     {
         return null;
     }
     // If expression does not return double, we'll get an error. - D.H.
     if (body.Type != typeof(double))
     {
         return null;
     }
     var expressionTree = Expression.Lambda<Func<double>>(body);
     return expressionTree;
 }
Beispiel #3
0
        Expression CreatePropertyAccessExpression(Node root)
        {
            string figureName = root.Children[0].Token.Text;
            string propertyName = root.Children[1].Token.Text;

            IFigure figure = Binder.ResolveFigure(figureName);
            if (figure == null)
            {
                Status.AddUnknownIdentifierError(figureName);
                return null;
            }

            if (!Binder.IsFigureAllowed(figure))
            {
                Status.AddDependencyCycleError(figureName);
                return null;
            }

            Type type = figure.GetType();
            var property = type.GetProperty(propertyName,
                BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
            if (property == null)
            {
                Status.AddPropertyNotFoundError(figure, propertyName);
                return null;
            }

            Status.Dependencies.Add(figure);
            var figureExpression = Expression.Constant(figure);
            var propertyExpression = Expression.Property(figureExpression, property);
            return propertyExpression;
        }
Beispiel #4
0
        Expression CreateUnaryExpression(Node root)
        {
            Expression operand = CreateExpressionCore(root.Children[0]);
            if (operand == null)
            {
                return null;
            }

            return Expression.Negate(operand);
        }
Beispiel #5
0
 Expression CreateExpressionCore(Node root)
 {
     switch (root.Kind)
     {
         case NodeType.Negation:
             return CreateUnaryExpression(root);
         case NodeType.Addition:
         case NodeType.Subtraction:
         case NodeType.Multiplication:
         case NodeType.Division:
         case NodeType.Power:
             return CreateBinaryExpression(root);
         case NodeType.Variable:
             return CreateIdentifierExpression(root);
         case NodeType.Constant:
             return CreateLiteralExpression(Convert.ToDouble(root.Token.Text));
         case NodeType.FunctionCall:
             return CreateCallExpression(root);
         case NodeType.PropertyAccess:
             return CreatePropertyAccessExpression(root);
         default:
             return null;
     }
 }
Beispiel #6
0
        Expression CreateIdentifierExpression(Node root)
        {
            var text = root.Token.Text;
            Expression resolveTwoPoints = ResolveTwoPoints(text);
            if (resolveTwoPoints != null)
            {
                return resolveTwoPoints;
            }

            var parameter = Binder.Resolve(text);
            if (parameter == null)
            {
                Status.AddUnknownIdentifierError(text);
            }

            return parameter;
        }
Beispiel #7
0
        Expression CreateBinaryExpression(Node node)
        {
            Expression left = CreateExpressionCore(node.Children[0]);
            Expression right = CreateExpressionCore(node.Children[1]);

            if (left == null || right == null)
            {
                return null;
            }

            switch (node.Kind)
            {
                case NodeType.Addition:
                    return Expression.Add(left, right);
                case NodeType.Subtraction:
                    return Expression.Subtract(left, right);
                case NodeType.Multiplication:
                    return Expression.Multiply(left, right);
                case NodeType.Division:
                    return Expression.Divide(left, right);
                case NodeType.Power:
                    return Expression.Power(left, right);
            }
            return null;
        }
Beispiel #8
0
        Expression CreateCallExpression(Node root)
        {
            string functionName = root.Token.Text;
            MethodInfo method = Binder.ResolveMethod(functionName);
            if (method == null)
            {
                Status.AddMethodNotFoundError(functionName);
                return null;
            }

            var arguments = root.Children;
            if (arguments.Count == 1)
            {
                var argument = CreateExpressionCore(arguments[0]);
                if (argument == null)
                {
                    return null;
                }

                return Expression.Call(method, argument);
            }

            return CreatePointFunctionCallExpression(method, arguments);
        }
Beispiel #9
0
 private Node PropertyAccess(Node left, Node right)
 {
     return new Node(NodeType.PropertyAccess, left, right);
 }
Beispiel #10
0
 private Node ParseFunctionCall()
 {
     var result = new Node(NodeType.FunctionCall, Current);
     AdvanceToken();
     AdvanceToken(TokenType.OpenParen);
     AddArgument(result, ParseExpression());
     while (CurrentTokenKind == TokenType.Comma)
     {
         AdvanceToken();
         AddArgument(result, ParseExpression());
     }
     AdvanceToken(TokenType.CloseParen);
     return result;
 }
Beispiel #11
0
 private Node Negation(Node unaryOperand)
 {
     return new Node(NodeType.Negation, unaryOperand);
 }
Beispiel #12
0
 private Node BinaryOperator(NodeType operationType, Node leftOperand, Node rightOperand)
 {
     return new Node(operationType, leftOperand, rightOperand);
 }
Beispiel #13
0
 private void AddArgument(Node functionCall, Node argument)
 {
     functionCall.Children.Add(argument);
 }