예제 #1
0
        public static Expression Compile(string exp)
        {
            var functions = new FunctionManager();

            return(Compile(Tokenize(exp), functions));
        }
예제 #2
0
        private static Expression InternalCompile(LinkedListNode <Token> first, LinkedListNode <Token> last, FunctionManager functions, int level = 0)
        {
            if (first.Value.Type == TokenType.SBracket && MatchingBracketForward(first) == last)
            {
                return(InternalCompile(first.Next, last.Previous, functions, 0));
            }
            LinkedListNode <Token> token;
            int brackets = 0;

            switch (level)
            {
            case 0:
                Debug.Assert(level == 0);
                // Additions and subtractions
                token = last;
                while (token != first.Previous)
                {
                    if (token.Value.Type == TokenType.SBracket)
                    {
                        brackets--;
                    }
                    else if (token.Value.Type == TokenType.EBracket)
                    {
                        brackets++;
                    }
                    else if (brackets == 0)
                    {
                        if (token.Value.Value == "+")
                        {
                            return(functions.Operator("+").Create(InternalCompile(first, token.Previous, functions, level), InternalCompile(token.Next, last, functions, level)));
                        }
                        if (token.Value.Value == "-")
                        {
                            return(functions.Operator("-").Create(InternalCompile(first, token.Previous, functions, level), InternalCompile(token.Next, last, functions, level)));
                        }
                    }
                    else if (brackets <= 0)
                    {
                        throw new Exception("SumTingWong. Tokens: " + ContainerUtils.AsString(first, last));
                    }
                    token = token.Previous;
                }
                Debug.Assert(brackets == 0, "Unbalanced brackets");
                level++;
                goto case 1;

            case 1:
                Debug.Assert(level == 1);
                // Multiplications and divisions
                token = last;
                while (token != first.Previous)
                {
                    if (token.Value.Type == TokenType.SBracket)
                    {
                        brackets--;
                    }
                    else if (token.Value.Type == TokenType.EBracket)
                    {
                        brackets++;
                    }
                    else if (brackets == 0)
                    {
                        if (token.Value.Value == "*")
                        {
                            return(functions.Operator("*").Create(InternalCompile(first, token.Previous, functions, level), InternalCompile(token.Next, last, functions, level)));
                        }
                        if (token.Value.Value == "/")
                        {
                            return(functions.Operator("/").Create(InternalCompile(first, token.Previous, functions, level), InternalCompile(token.Next, last, functions, level)));
                        }
                    }
                    else if (brackets <= 0)
                    {
                        throw new Exception("SumTingWong. Tokens: " + ContainerUtils.AsString(first, last));
                    }
                    token = token.Previous;
                }
                if (brackets != 0)
                {
                    throw new Exception("Unbalanced brackets");
                }
                level++;
                goto case 2;

            case 2:
                Debug.Assert(level == 2);
                // Powers
                token = last;
                while (token != first.Previous)
                {
                    if (token.Value.Type == TokenType.SBracket)
                    {
                        brackets--;
                    }
                    else if (token.Value.Type == TokenType.EBracket)
                    {
                        brackets++;
                    }
                    else if (brackets == 0)
                    {
                        if (token.Value.Value == "^")
                        {
                            return(functions.Operator("^").Create(InternalCompile(first, token.Previous, functions, level), InternalCompile(token.Next, last, functions, level)));
                        }
                    }
                    else if (brackets <= 0)
                    {
                        throw new Exception("SumTingWong. Tokens: " + ContainerUtils.AsString(first, last));
                    }
                    token = token.Previous;
                }
                if (brackets != 0)
                {
                    throw new Exception("Unbalanced brackets");
                }
                level++;
                goto case 3;

            case 3:
                Debug.Assert(level == 3);
                // Functions & variables
                token = last;
                while (token != first.Previous)
                {
                    if (token.Value.Type == TokenType.SBracket)
                    {
                        brackets--;
                    }
                    else if (token.Value.Type == TokenType.EBracket)
                    {
                        brackets++;
                    }
                    else if (brackets == 0)
                    {
                        if (token.Value.Type == TokenType.Identifier)
                        {
                            if (token.Next != null && token.Next.Value.Type == TokenType.SBracket)
                            {
                                return(functions.Function(token.Value.Value).Create(FunctionArgumentsCompile(token.Next.Next, MatchingBracketForward(token.Next), functions)));
                            }
                            else
                            {
                                return(new Variable(token.Value.Value));
                            }
                        }
                    }
                    else if (brackets <= 0)
                    {
                        throw new Exception("SumTingWong. Tokens: " + ContainerUtils.AsString(first, last));
                    }
                    token = token.Previous;
                }
                if (brackets != 0)
                {
                    throw new Exception("Unbalanced brackets");
                }
                level++;
                goto case 4;

            case 4:
                Debug.Assert(level == 4);
                // Literals
                token = last;
                while (token != first.Previous)
                {
                    if (token.Value.Type == TokenType.SBracket)
                    {
                        brackets--;
                    }
                    else if (token.Value.Type == TokenType.EBracket)
                    {
                        brackets++;
                    }
                    else if (brackets == 0)
                    {
                        if (token.Value.Type == TokenType.Value)
                        {
                            return(new ValueExpression(double.Parse(token.Value.Value)));
                        }
                    }
                    else if (brackets <= 0)
                    {
                        throw new Exception("SumTingWong. Tokens: " + ContainerUtils.AsString(first, last));
                    }
                    token = token.Previous;
                }
                if (brackets != 0)
                {
                    throw new Exception("Unbalanced brackets");
                }
                //level++;
                goto default;

            default:
                throw new Exception();
            }
        }
예제 #3
0
        private static Expression[] FunctionArgumentsCompile(LinkedListNode <Token> first, LinkedListNode <Token> last, FunctionManager functions)
        {
            LinkedListNode <Token> prevComma = first; // Actually just after the previous comma.
            LinkedListNode <Token> token     = first;
            List <Expression>      exps      = new List <Expression>();
            int brackets = 0;

            while (token != last)
            {
                if (token.Value.Type == TokenType.SBracket)
                {
                    brackets--;
                }
                else if (token.Value.Type == TokenType.EBracket)
                {
                    brackets++;
                }
                else if (brackets == 0 && token.Value.Type == TokenType.Comma)
                {
                    exps.Add(InternalCompile(prevComma, token.Previous, functions));
                    prevComma = token.Next;
                }
                token = token.Next;
            }
            Debug.Assert(brackets == 0);
            exps.Add(InternalCompile(prevComma, last.Previous, functions));
            return(exps.ToArray());
        }
예제 #4
0
 public static Expression Compile(LinkedList <Token> tokens, FunctionManager functions)
 {
     return(InternalCompile(tokens.First, tokens.Last, functions));
 }