示例#1
0
        public Expression(object[] tokens)
        {
            try
            {
                List<object> ex = new List<object>();
                for (int i = 0; i < tokens.Length; i++)
                    ex.Add(tokens[i]);

                int index = 0;

                for (index = 1; index < ex.Count; index++)
                {
                    if (ex[index - 1] is NumberToken && ex[index] is IdentifierToken)
                    {
                        var num = ex[index - 1] as NumberToken;
                        var unit = ex[index] as IdentifierToken;
                        ex.RemoveAt(index);
                        var d = new Dictionary<string, Unit>();
                        d.Add(unit.Text, new Unit(unit.Text, 1));
                        ex[index - 1] = new NumberType(num.Text, new UnitType(d));
                        index--;
                    }
                }
                for (index = 0; index < ex.Count; index++)
                {
                    if (ex[index] is ParenthOpenToken)
                    {
                        int ti = index;
                        index++;
                        int nest = 1;
                        List<object> tt = new List<object>();
                        while (true)
                        {
                            if (ex[index] is ParenthOpenToken)
                                nest++;
                            if (ex[index] is ParenthCloseToken)
                                nest--;
                            if (nest == 0)
                            {
                                index++;
                                break;
                            }

                            tt.Add(ex[index]);

                            index++;
                        }

                        for (int i = index - 1; i > ti; i--)
                        {
                            ex.RemoveAt(i);
                        }
                        ex[ti] = new Expression(tt.ToArray()).RootExpr;
                        index = ti + 1;
                    }
                }
                for (index = 0; index < ex.Count - 2; index++)
                {
                    if (ex[index] is IdentifierToken && ex[index + 1] is ListStartToken)
                    {
                        int ti = index + 2;
                        List<ExprNode> p = new List<ExprNode>();
                        int nest = 0;
                        while (!(ex[ti] is ListEndToken))
                        {
                            List<object> tl = new List<object>();
                            if (ex[ti] is ListSeperatorToken)
                                ti++;

                            while (!(ex[ti] is ListSeperatorToken) && !(ex[ti] is ListEndToken) || nest != 0)
                            {
                                if (ex[ti] is ListStartToken)
                                    nest++;
                                if (ex[ti] is ListEndToken)
                                    nest--;
                                tl.Add(ex[ti++]);
                            }
                            p.Add(new Expression(tl.ToArray()).RootExpr);
                        }
                        for (int i = ti; i > index; i--)
                            ex.RemoveAt(i);
                        ex[index] = new FunctionNode(((IdentifierToken)ex[index]).Text, p.ToArray());
                    }
                }
                //Number Lists
                for (index = 0; index < ex.Count - 1; index++)
                {
                    if (ex[index] is ListStartToken)
                    {
                        int ti = index + 1;
                        List<ExprNode> p = new List<ExprNode>();
                        int nest = 0;
                        while (!(ex[ti] is ListEndToken))
                        {
                            List<object> tl = new List<object>();
                            if (ex[ti] is ListSeperatorToken)
                                ti++;

                            while (!(ex[ti] is ListSeperatorToken) && !(ex[ti] is ListEndToken) || nest != 0)
                            {
                                if (ex[ti] is ListStartToken)
                                    nest++;
                                if (ex[ti] is ListEndToken)
                                    nest--;
                                tl.Add(ex[ti++]);
                            }
                            p.Add(new Expression(tl.ToArray()).RootExpr);
                        }
                        for (int i = ti; i > index; i--)
                            ex.RemoveAt(i);
                        ex[index] = new ListNode(p.ToArray());
                    }
                }
                //=======
                for (index = 0; index < ex.Count; index++)
                {
                    if (ex[index] is PowToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new PowerNode(Expr(left), Expr(right));
                        index--;
                    }
                }
                for (index = 0; index < ex.Count; index++)
                {
                    if (ex[index] is MulToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new MultiplicationNode(Expr(left), Expr(right));
                        index--;
                    }
                    if (ex[index] is DivToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new DivisionNode(Expr(left), Expr(right));
                        index--;
                    }
                    if (ex[index] is ModToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new ModuloNode(Expr(left), Expr(right));
                        index--;
                    }
                }
                for (index = 0; index < ex.Count; index++)
                {
                    if (ex[index] is AddToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new AdditionNode(Expr(left), Expr(right));
                        index--;
                    }
                    if (ex[index] is SubToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new SubtractionNode(Expr(left), Expr(right));
                        index--;
                    }
                }
                for (index = 0; index < ex.Count; index++)
                {
                    if (ex[index] is EqualToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.Equal);
                        index--;
                    }
                    if (ex[index] is NotEqualToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.NotEqual);
                        index--;
                    }
                    if (ex[index] is LessToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.Less);
                        index--;
                    }
                    if (ex[index] is LessEqualToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.LessEqual);
                        index--;
                    }
                    if (ex[index] is GreaterToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.Greater);
                        index--;
                    }
                    if (ex[index] is GreaterEqualToken)
                    {
                        var left = ex[index - 1];
                        var right = ex[index + 1];
                        ex.RemoveAt(index + 1);
                        ex.RemoveAt(index);
                        ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.GreaterEqual);
                        index--;
                    }
                }

                RootExpr = Expr(ex[0]);
                Console.WriteLine(RootExpr);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                throw new ExpressionException(((Token)tokens[0]).Line, -1, "Invalid expression.  (Forgot closing parenthesis?)");
            }
        }
        /// <summary>
        /// Builds a StatementList from a set of tokens.
        /// </summary>
        /// <param name="tokens">The array of token arrays to build from.</param>
        /// <returns>A statement list from the tokens.</returns>
        public static StatementList Build(Token[][] tokens)
        {
            var sl = new StatementList();

            for (int i = 0; i < tokens.Length; i++)
            {
                //if (tokens[i].Length > 2)
                {
                    if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is AssignmentToken)
                        sl.Add(new AssignmentStatement(tokens[i][0].Text, new Expression(tokens[i].SubArray(2, tokens[i].Length - 2))));
                    else if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is AddAssignmentToken)
                        sl.Add(new AdditionAssignmentStatement(tokens[i][0].Text, new Expression(tokens[i].SubArray(2, tokens[i].Length - 2))));
                    else if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is SubAssignmentToken)
                        sl.Add(new SubtractionAssignmentStatement(tokens[i][0].Text, new Expression(tokens[i].SubArray(2, tokens[i].Length - 2))));
                    if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is MulAssignmentToken)
                        sl.Add(new MultiplicationAssignmentStatement(tokens[i][0].Text, new Expression(tokens[i].SubArray(2, tokens[i].Length - 2))));
                    if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is DivAssignmentToken)
                        sl.Add(new DivisionAssignmentStatement(tokens[i][0].Text, new Expression(tokens[i].SubArray(2, tokens[i].Length - 2))));

                    else if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is ListStartToken)
                        sl.Add(new FunctionStatement(new Expression(tokens[i]).RootExpr as FunctionNode));
                    else if (tokens[i].Length > 1 && tokens[i][0] is ReturnToken)
                        sl.Add(new ReturnStatement(new Expression(tokens[i].SubArray(1, tokens[i].Length - 1))));
                    else if (tokens[i].Length > 4 && tokens[i][0] is DefineToken)
                    {
                        string name = tokens[i][1].Text;
                        if (!(tokens[i][2] is ListStartToken))
                            throw Err("Expected parameter list.", tokens[i][2]);

                        int ti = 3;
                        List<string> p = new List<string>();
                        while (!(tokens[i][ti] is ListEndToken))
                        {
                            if (tokens[i][ti] is ListSeperatorToken)
                                ti++;
                            p.Add(tokens[i][ti++].Text);
                        }

                        if (!(tokens[i][ti + 1] is BodyOpenToken))
                            throw Err("Expected body open.", tokens[i][ti + 1]);

                        i++;
                        List<Token[]> ftl = ReadBody(tokens, ref i);
                        //i++;
                        
                        sl.Add(new FunctionDefineStatement(name, p.ToArray(), Build(ftl.ToArray())));
                    }
                    else if (tokens[i][0] is WhileToken)
                    {
                        var conditional = new Expression(tokens[i].SubArray(1, tokens[i].Length - 2));
                        if (!(tokens[i][tokens[i].Length - 1] is BodyOpenToken))
                            throw Err("Expected body open.", tokens[i][tokens[i].Length - 1]);

                        i++;
                        List<Token[]> ftl = ReadBody(tokens, ref i);

                        sl.Add(new WhileStatement(conditional.RootExpr, Build(ftl.ToArray())));
                    }
                    else if (tokens[i][0] is ForToken)
                    {
                        if (!(tokens[i][1] is IdentifierToken))
                            throw Err("Variable name must follow for token.", tokens[i][1]);
                        var vn = tokens[i][1].Text;
                        if (!(tokens[i][2] is FromToken))
                            throw Err("From token must follow variable name.", tokens[i][2]);
                        List<Token> fromTokens = new List<Token>();
                        int n;
                        for (n = 3; n < tokens[i].Length; n++)
                            if (tokens[i][n] is ToToken)
                                break;
                            else
                                fromTokens.Add(tokens[i][n]);
                        if (n == tokens[i].Length)
                            throw Err("To token must follow From expression.", tokens[i][n]);
                        n++;

                        var fromExpr = new Expression(fromTokens.ToArray());

                        List<Token> toTokens = new List<Token>();
                        for (; n < tokens[i].Length; n++)
                            if (tokens[i][n] is BodyOpenToken || tokens[i][n] is IncToken)
                                break;
                            else
                                toTokens.Add(tokens[i][n]);
                        if (n == tokens[i].Length)
                            throw Err("Body Open token or Inc token must follow To expression.", tokens[i][n]);

                        var toExpr = new Expression(toTokens.ToArray());

                        Expression incExpr;
                        if (tokens[i][n] is IncToken)
                        {
                            n++;
                            List<Token> incTokens = new List<Token>();
                            for (; n < tokens[i].Length; n++)
                                if (tokens[i][n] is BodyOpenToken)
                                    break;
                                else
                                    incTokens.Add(tokens[i][n]);
                            if (n == tokens[i].Length)
                                throw Err("Body Open token must follow Inc expression.", tokens[i][n]);

                            incExpr = new Expression(incTokens.ToArray());
                        }
                        else
                        {
                            incExpr = new Expression(new[] { new NumberToken("1") });
                        }

                        if (!(tokens[i][n] is BodyOpenToken))
                            throw Err("Body Open token expected.", tokens[i][n]);
                        

                        i++;
                        List<Token[]> ftl = ReadBody(tokens, ref i);

                        sl.Add(new ForStatement(vn, fromExpr.RootExpr, toExpr.RootExpr, incExpr.RootExpr, Build(ftl.ToArray())));
                    }
                    else if (tokens[i][0] is IfToken)
                    {
                        var conditional = new Expression(tokens[i].SubArray(1, tokens[i].Length - 2));
                        if (!(tokens[i][tokens[i].Length - 1] is BodyOpenToken))
                            throw Err("Expected body open.", tokens[i][tokens[i].Length - 1]);

                        i++;
                        List<Token[]> ftl = ReadBody(tokens, ref i);
                        var etl = new List<Token[]>();
                        if (tokens.Length > i + 1)
                            if (tokens[i + 1].Length > 0 && tokens[i + 1][0] is ElseToken)
                            {
                                i += 2;
                                etl = ReadBody(tokens, ref i);
                            }

                        sl.Add(new IfStatement(conditional.RootExpr, Build(ftl.ToArray()), Build(etl.ToArray())));
                    }
                }
            }

            return sl;
        }