Exemplo n.º 1
0
        public static BlockNode ProcessTokens(List <ScriptToken> tokens)
        {
            List <AstTreeNode> blockNodes = new List <AstTreeNode>();
            AstTreeNode        node       = new BlockNode(null);
            int count = 0;

            StripWhiteSpace(tokens);

            while (tokens.Count > 0)
            {
                count++;
                if (count > 1000)
                {
                    break;               // Limit to 1000 iterations while in development
                }
                if (tokens[0].Type == EScriptTokenType.RETURN)
                {
                    tokens.RemoveAt(0); // Last value in block is returned by default
                }
                ScriptToken scriptToken = tokens[0];

                if (scriptToken.Type == EScriptTokenType.NAME)
                {
                    node = new RootScopeMemberNode(
                        new LiteralNode <string>(scriptToken.Value)
                        );
                    tokens.RemoveAt(0);
                }
                else if (scriptToken.Type == EScriptTokenType.ASSIGN)
                {
                    node = AssignmentNode.Parse(node, scriptToken, tokens);
                }
                else if (scriptToken.Type == EScriptTokenType.IF)
                {
                    node = IfStatementNode.Parse(node, scriptToken, tokens);
                    blockNodes.Add(node);
                    node = null;
                }
                else if (scriptToken.Type == EScriptTokenType.FOR)
                {
                    node = ForStatementNode.Parse(node, scriptToken, tokens);
                    blockNodes.Add(node);
                    node = null;
                }
                else if (scriptToken.Type == EScriptTokenType.STRING_LITERAL)
                {
                    node = new LiteralNode <string>(scriptToken.Value);
                    tokens.RemoveAt(0);
                }
                else if (scriptToken.Type == EScriptTokenType.NUMBER_LITERAL)
                {
                    AstTreeNode _node;
                    if (scriptToken.Value.Contains("."))
                    {
                        _node = new FloatLiteralNode(scriptToken.Value);
                    }
                    else
                    {
                        _node = new IntegerLiteralNode(scriptToken.Value);
                    }

                    node = _node;
                    tokens.RemoveAt(0);
                }
                else if (scriptToken.Type == EScriptTokenType.PERIOD)
                {
                    if (tokens[1].Type == EScriptTokenType.NAME)
                    {
                        node = new ScopeMemberNode(
                            node,
                            new LiteralNode <string>(tokens[1].Value)
                            );
                        tokens.RemoveAt(0);
                        tokens.RemoveAt(0);
                    }
                }
                else if (scriptToken.Type == EScriptTokenType.L_BRACKET)
                {
                    if (node.GetType() == typeof(RootScopeMemberNode))
                    {
                        // indice
                    }
                    else
                    {
                        node = ArrayNode.Parse(node, scriptToken, tokens);
                    }
                }
                else if (scriptToken.Type == EScriptTokenType.L_PAREN)
                {
                    List <List <ScriptToken> > funcArgs = GetBlockTokens(tokens);
                    List <AstTreeNode>         nodes    = new List <AstTreeNode>();
                    ;
                    foreach (List <ScriptToken> arg in funcArgs)
                    {
                        nodes.Add(ProcessTokens(arg));
                    }
                    node = new FunctionCallNode(
                        node, // Previous node should be a NAME
                        new FunctionArgumentNode(nodes)
                        );
                }
                else if (scriptToken.Type == EScriptTokenType.SEMI_COLON)
                {
                    if (node != null)
                    {
                        blockNodes.Add(node);
                    }

                    node = null;
                    tokens.RemoveAt(0);
                }
                else if (ComparisonNode.Matches(tokens))
                {
                    node = ComparisonNode.Parse(node, scriptToken, tokens);
                }
                else if (ArithmeticNode.Matches(tokens))
                {
                    AstTreeNode _node = ArithmeticNode.Parse(node, scriptToken, tokens);
                    node = _node;
                }
                else if (ArithmeticAssignmentNode.Matches(tokens))
                {
                    node = ArithmeticAssignmentNode.Parse(node, scriptToken, tokens);
                }
                else if (scriptToken.Type == EScriptTokenType.WHITESPACE)
                {
                    tokens.RemoveAt(0);
                }
                else if (scriptToken.Type == EScriptTokenType.BOOLEAN_LITERAL)
                {
                    node = new BooleanLiteralNode(tokens[0].Value);
                    tokens.RemoveAt(0);
                }
                else if (scriptToken.Type == EScriptTokenType.NULL_LITERAL)
                {
                    node = new LiteralNode <object>(null);
                    tokens.RemoveAt(0);
                }
                else
                {
                    string code = ScriptTree.ToCode(tokens, 10);
                    Console.WriteLine($"Syntax Error.Near {code}");
                }
            }

            if (node != null)
            {
                blockNodes.Add(node);
            }

            return(new BlockNode(blockNodes));
        }