Exemplo n.º 1
0
        private static Func <double, double> CompileFunctionCall(NonterminalSyntaxNode node, CompilationContext context)
        {
            int childCount = node.Children.Count;

            if (childCount < 2)
            {
                context.AddError(ErrorType.ArgumentExpected);
                return(null);
            }

            var    functionNode = (TerminalSyntaxNode)node.Children[0];
            string functionName = functionNode.Token.Text;

            if (childCount == 2)
            {
                Func <double, double> monadicFunction = context.ResolveMonadicFunction(functionName);
                if (monadicFunction == null)
                {
                    context.AddErrorWithParameter(ErrorType.UnknownFunction, functionNode);
                    return(null);
                }

                Func <double, double> argument = Compile(node.Children[1], context);
                if (argument == null)
                {
                    return(null);
                }

                return(x => monadicFunction(argument(x)));
            }

            if (childCount == 3)
            {
                Func <double, double, double> dyadicFunction = context.Symbols.ResolveDyadicFunction(functionName);
                if (dyadicFunction == null)
                {
                    context.AddErrorWithParameter(ErrorType.UnknownFunction, functionNode);
                    return(null);
                }

                Func <double, double> firstArgument = Compile(node.Children[1], context);
                if (firstArgument == null)
                {
                    return(null);
                }

                Func <double, double> secondArgument = Compile(node.Children[2], context);
                if (secondArgument == null)
                {
                    return(null);
                }

                return(x => dyadicFunction(firstArgument(x), secondArgument(x)));
            }

            context.AddError(ErrorType.ExcessArguments);
            return(null);
        }
Exemplo n.º 2
0
        private static Func <double, double> CompileUnaryOperation(NonterminalSyntaxNode node, CompilationContext context)
        {
            Func <double, double> operand = Compile(node.Children[0], context);

            if (operand == null)
            {
                return(null);
            }

            return(x => - 1.0 * operand(x));
        }
Exemplo n.º 3
0
        private static Func <double, double> CompileBinaryOperation(NonterminalSyntaxNode node, CompilationContext context)
        {
            Func <double, double> left = Compile(node.Children[0], context);

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

            Func <double, double> right = Compile(node.Children[1], context);

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

            switch (node.Type)
            {
            case NodeType.Addition:
                return(x => left(x) + right(x));

            case NodeType.Division:
                return(x => left(x) / right(x));

            case NodeType.Modulus:
                return(x => left(x) % right(x));

            case NodeType.Multiplication:
                return(x => left(x) * right(x));

            case NodeType.Power:
                return(x => Math.Pow(left(x), right(x)));

            case NodeType.Subtraction:
                return(x => left(x) - right(x));

            default:
                throw new InvalidOperationException($"Unsupported binary operation of NodeType {node.Type}");
            }
        }