Esempio n. 1
0
        public skipInfo skipChain(List <Token> Tokens, int startingPoint)
        {
            int start = startingPoint;
            int index = startingPoint;
            int end   = 0;

            Token token = Tokens[index];

            if (!token.IsValuable())
            {
                return(new skipInfo {
                    start = start, end = end, delta = 0
                });
            }

            while (true)
            {
                //Console.WriteLine(token);

                if (token.Value == "(")
                {
                    skipInfo skip = engine.expressionParser.SkipFromTo("(", ")", Tokens, index);
                    index = skip.end + 1;
                }
                else if (token.Value == "[")
                {
                    skipInfo skip = engine.expressionParser.SkipFromTo("[", "]", Tokens, index);
                    index = skip.end + 1;
                }
                else if (token.Value == "." || token.IsValuable())
                {
                    skipInfo skip = engine.expressionParser.SkipAccess(Tokens, index);
                    index = skip.end;
                }
                else
                {
                    break;
                }

                if (index == Tokens.Count)
                {
                    break;
                }

                token = Tokens[index];
            }

            end = index;
            int delta = index - start;

            return(new skipInfo {
                start = start, end = end, delta = delta
            });
        }
Esempio n. 2
0
        List <Token> GetSurroundedTokens(string open, string close, int start, List <Token> Tokens)
        {
            int index = start;

            int      i    = index + 1;
            skipInfo skip = engine.expressionParser.SkipFromTo(open, close, Tokens, index);
            int      end  = skip.end;

            index = skip.end;

            return(Tokens.GetRange(i, end - i));
        }
Esempio n. 3
0
        /// <summary>
        /// Parses a list of tokens into an expression recursively
        /// </summary>
        public Node ParseExpression(Node branch, List <Token> Tokens)
        {
            if (Tokens.Count == 1)
            {
                // return resulting end node
                return(new Node {
                    Body = Tokens[0].Value,
                    //Value = null,
                    TokenType = "" + Tokens[0].Type,
                    Token = Tokens[0],
                });
            }

            // Create left and right token buffers
            List <Token> leftBuffer  = new List <Token>();
            List <Token> rightBuffer = new List <Token>();

            bool isInPars          = false;
            bool isMethodCall      = false;
            bool isIndexing        = false;
            bool isArrayLiteral    = false;
            bool isFunctionLiteral = false;
            bool isChain           = false;

            int accessEnd = 0;

            // Do logic in delegate so we can easily exit out of it when we need to
            Action loop = () => {
                foreach (OperatorGroup OP in OperatorPrecedence)
                {
                    foreach (Operator Operator in OP.Operators)
                    {
                        int  i       = 0;
                        bool CanLoop = Tokens.Count > 0;

                        while (CanLoop)
                        {
                            skipInfo s = skipChain(Tokens, i);

                            if (s.delta > 0)
                            {
                                i = s.end - 1;
                                if (s.start == 0 && i == Tokens.Count - 1 && s.delta != 0)
                                {
                                    isChain = true;
                                    return;
                                }
                            }

                            Token token         = Tokens[i];
                            Token previousToken = i >= 1 ? Tokens[i - 1] : null;

                            if (token.Value == "func")
                            {
                                skipInfo skip = engine.expectValue("(", Tokens, i);
                                i += skip.delta;

                                int start = i;
                                skip = engine.expressionParser.SkipFromTo("(", ")", Tokens, i);
                                i   += skip.delta;

                                skip = engine.expressionParser.SkipFromTo("{", "}", Tokens, i);
                                i   += skip.delta;

                                if (start == 1 && skip.end == Tokens.Count - 1)
                                {
                                    isFunctionLiteral = true;
                                    return;
                                }
                            }

                            if (GeneralParser.Keywords.Contains(Tokens[i].Value))
                            {
                                engine.throwError("Unexpected keyword '" + Tokens[i].Value + "' found", Tokens[i], 2);
                            }

                            //if (token.Value == "(") {
                            //    if (previousToken != null) {
                            //        // Previous token was identifier; possible method call
                            //        if (previousToken.Type == TokenTypes.Identifier) {
                            //            skipInfo skip = engine.expressionParser.SkipFromTo("(", ")", Tokens, i);
                            //            i += skip.delta;

                            //            if (skip.start == 1 && skip.end == Tokens.Count - 1) {
                            //                isMethodCall = true;
                            //                return;
                            //            }
                            //        }
                            //    }
                            //}
                            if (token.Value == "(")
                            {
                                skipInfo skip = engine.expressionParser.SkipFromTo("(", ")", Tokens, i);
                                i += skip.delta;

                                if (skip.start == 0 && skip.end == Tokens.Count - 1)
                                {
                                    isInPars = true;
                                    return;
                                }
                            }
                            //if (token.Value == "[") {
                            //    if (previousToken != null) {
                            //        // Previous token was identifier or string; possible indexing
                            //        if (previousToken.Type == TokenTypes.Identifier || previousToken.Type == TokenTypes.StringLiteral) {
                            //            skipInfo skip = engine.expressionParser.SkipFromTo("[", "]", Tokens, i);
                            //            i += skip.delta;

                            //            if (skip.start == 1 && skip.end == Tokens.Count - 1) {
                            //                isIndexing = true;
                            //                return;
                            //            }
                            //        }
                            //    }
                            //}
                            if (token.Value == "[")
                            {
                                skipInfo skip = engine.expressionParser.SkipFromTo("[", "]", Tokens, i);
                                i += skip.delta;

                                if (skip.start == 0 && skip.end == Tokens.Count - 1)
                                {
                                    isArrayLiteral = true;
                                    return;
                                }
                            }
                            if (token.Value == Operator.Operation)
                            {
                                // Fill left and right buffers
                                leftBuffer  = Tokens.GetRange(0, i);
                                rightBuffer = Tokens.GetRange(i + 1, Tokens.Count - i - 1);

                                bool HasRequiredLeftTokens  = leftBuffer.Count > 0;
                                bool HasRequiredRightTokens = rightBuffer.Count > 0;

                                if (OP.Members == 1)
                                {
                                    if (OP.IsPostfix)
                                    {
                                        HasRequiredRightTokens = true;
                                    }
                                    else
                                    {
                                        HasRequiredLeftTokens = true;
                                    }
                                }

                                if (HasRequiredLeftTokens && HasRequiredRightTokens)
                                {
                                    // Create operation node with type and body
                                    Node NewNode = new Node();
                                    NewNode.Body      = Operator.OperationName;
                                    NewNode.TokenType = "" + token.Type;
                                    NewNode.Token     = token;

                                    if (OP.Members == 1)
                                    {
                                        // Parse unary and do postfix logic

                                        Node LeftNode = !OP.IsPostfix ? null : ParseExpression(NewNode, leftBuffer);
                                        NewNode.Add(LeftNode);

                                        Node RightNode = OP.IsPostfix ? null : ParseExpression(NewNode, rightBuffer);
                                        NewNode.Add(RightNode);
                                    }
                                    else
                                    {
                                        // Parse operators that need 2 sides

                                        Node LeftNode = ParseExpression(NewNode, leftBuffer);
                                        NewNode.Add(LeftNode);

                                        Node RightNode = ParseExpression(NewNode, rightBuffer);
                                        NewNode.Add(RightNode);
                                    }

                                    branch.Add(NewNode);
                                    return;
                                }
                                else
                                {
                                    engine.throwError("Missing member of operation!", token, 10);
                                }
                            }

                            // Check if we're still in bounds
                            CanLoop = OP.LeftAssociate ? i < Tokens.Count - 1 : ((Tokens.Count - 1) - i) > 0;
                            i++;
                        }
                    }
                }
            };

            loop();

            if (isChain)
            {
                return(ParseChain(Tokens));
            }

            // Parse expression within parenthesis if it's completely surrounded
            if (isInPars)
            {
                return(ParseExpression(branch, Tokens.GetRange(1, Tokens.Count - 2)));
            }

            // Parse method call
            if (isMethodCall)
            {
                ParseResult result = ParseCall(Tokens, accessEnd);
                return(result.node);
            }

            // Parse indexing
            if (isIndexing)
            {
                ParseResult result = ParseIndexing(Tokens);
                return(result.node);
            }

            // Parse indexing
            if (isArrayLiteral)
            {
                ParseResult result = ParseArrayLiteral(Tokens);
                return(result.node);
            }

            // Parse function literal
            if (isFunctionLiteral)
            {
                ParseResult result = engine.methodParser.ParseFunctionLiteral(Tokens.GetRange(1, Tokens.Count - 1));
                return(result.node);
            }

            return(null);
        }
Esempio n. 4
0
        public Node ParseChain(List <Token> Tokens)
        {
            Node node = new Node();

            if (Tokens.Count == 2)
            {
                engine.throwError("Access operator can only be used after a value!", Tokens[0]);
            }

            if (Tokens.Count == 1)
            {
                return(ParseExpression(node, Tokens));
            }

            List <Token> Reverse = Tokens.GetRange(0, Tokens.Count);

            Reverse.Reverse();

            if (Reverse[0].Value == "]")
            {
                skipInfo skip = SkipFromTo("]", "[", Reverse, 0);

                if (skip.end + 1 >= Reverse.Count)
                {
                    engine.throwError("Indexing operator needs left hand value!", Reverse[skip.end]);
                }
                else if (Reverse[skip.end + 1].Value == ".")
                {
                    engine.throwError("Indexing operator needs left hand value!", Reverse[skip.end]);
                }

                Node getterNode = new Node();
                getterNode.Add(ParseChain(Tokens.GetRange(0, Tokens.Count - (skip.end + 1))));
                getterNode.Body      = "Getter";
                getterNode.TokenType = "Getter";
                node.Add(getterNode);

                //List<Token> ExpressionTokens = Reverse.GetRange(1, skip.end - 1);
                //ExpressionTokens.Reverse();
                //node.Add(ParseExpression(node, ExpressionTokens));

                List <Token> ArgumentTokens = Reverse.GetRange(0, skip.end + 1);
                ArgumentTokens.Reverse();

                ParseResult result        = engine.generalParser.parseSurroundedExpressions("[", "]", 0, ArgumentTokens);
                Node        argumentsNode = result.node;
                argumentsNode.Body      = "Arguments";
                argumentsNode.TokenType = "Arguments";
                node.Add(argumentsNode);

                node.Body      = "Index";
                node.TokenType = "Index";
            }
            else if (Reverse[0].Value == ")")
            {
                skipInfo skip = SkipFromTo(")", "(", Reverse, 0);

                if (skip.end + 1 >= Reverse.Count)
                {
                    engine.throwError("Call operator needs left hand value!", Reverse[skip.end]);
                }
                else if (Reverse[skip.end + 1].Value == ".")
                {
                    engine.throwError("Call operator needs left hand value!", Reverse[skip.end]);
                }

                Node getterNode = new Node();
                getterNode.Add(ParseChain(Tokens.GetRange(0, Tokens.Count - (skip.end + 1))));
                getterNode.Body      = "Getter";
                getterNode.TokenType = "Getter";
                node.Add(getterNode);

                List <Token> ArgumentTokens = Reverse.GetRange(0, skip.end + 1);
                ArgumentTokens.Reverse();

                ParseResult result        = engine.generalParser.parseSurroundedExpressions("(", ")", 0, ArgumentTokens);
                Node        argumentsNode = result.node;
                argumentsNode.Body      = "Arguments";
                argumentsNode.TokenType = "Arguments";
                node.Add(argumentsNode);

                node.Body      = "Call";
                node.TokenType = "Call";
            }
            else
            {
                node.Body      = "access";
                node.TokenType = "" + TokenTypes.Punctuator;

                node.Add(ParseExpression(node, new List <Token> {
                    Reverse[0]
                }));
                node.Add(ParseChain(Tokens.GetRange(0, Tokens.Count - 2)));
            }

            return(node);
        }