예제 #1
0
        /// <summary>
        ///     Parses a conditional statement.
        /// </summary>
        public ParseResult ParseConditional(List <Token> tokens)
        {
            var node       = new ConditionalNode();
            var scopeCheck = new ScopeCheck();

            for (int i = 0; i < tokens.Count; i++)
            {
                var token = tokens[i];

                scopeCheck.Check(token);

                if (token.Equals("?", TokenTypes.Punctuator) && scopeCheck.IsInScope)
                {
                    SkipInfo skip = SkipFromTo("?", ":", tokens, i);

                    var conditionNode = ParseClean(tokens.GetRange(0, i));
                    var successNode   = ParseClean(tokens.GetRange(i + 1, skip.Delta - 1));
                    var failNode      = ParseClean(tokens.GetRange(skip.End + 1, tokens.Count - (skip.End + 1)));

                    node.Condition = conditionNode ?? throw new SkryptException("Syntax error, condition statement can't be empty");
                    node.Pass      = successNode ?? throw new SkryptException("Syntax error, consequent statement can't be empty");
                    node.Fail      = failNode ?? throw new SkryptException("Syntax error, alternative statement can't be empty");

                    return(new ParseResult {
                        Node = node, Delta = tokens.Count
                    });
                }
            }

            _engine.ThrowError("Syntax error, conditional statement incomplete", tokens[0]);
            return(null);
        }
예제 #2
0
        /// <summary>
        ///     Parses a list of tokens into an expression node
        /// </summary>
        public ParseResult Parse(List <Token> tokens)
        {
            var node          = new Node();
            var delta         = 0;
            var addDelta      = 0;
            var deltaOffset   = 0;
            var scopeCheck    = new ScopeCheck();
            var previousToken = default(Token);

            if (tokens[0].Type == TokenTypes.EndOfExpression)
            {
                delta++;
                deltaOffset = 1;
            }

            // Loop until we hit the end of an expression, or consumed all tokens.
            while (true)
            {
                scopeCheck.Check(tokens[delta]);

                if (scopeCheck.IsInScope && tokens[delta].Type == TokenTypes.EndOfExpression)
                {
                    if (tokens[delta].Type == TokenTypes.EndOfExpression)
                    {
                        addDelta = 1;
                        break;
                    }
                }

                previousToken = tokens[delta];

                delta++;

                if (delta == tokens.Count)
                {
                    break;
                }
            }

            var returnNode = ParseClean(tokens.GetRange(deltaOffset, delta - deltaOffset));

            returnNode = ExpressionOptimiser.OptimiseExpressionNode(returnNode, _engine);

            delta += addDelta;

            return(new ParseResult {
                Node = returnNode, Delta = delta
            });
        }
예제 #3
0
        /// <summary>
        ///     Parses individual arguments as expressions.
        /// </summary>
        public void SetArguments(List <List <Token> > arguments, List <Token> tokens)
        {
            var i          = 0;
            var buffer     = new List <Token>();
            var isFirst    = true;
            var scopeCheck = new ScopeCheck();

            for (i = 0; i < tokens.Count; i++)
            {
                var token = tokens[i];
                buffer.Add(token);

                scopeCheck.Check(token);

                // Only set arguments if they're not inside nested function calls.
                if (scopeCheck.IsInScope)
                {
                    if (token.Equals(",", TokenTypes.Punctuator))
                    {
                        isFirst = false;

                        // Arguments cannot be empty.
                        if (buffer.Count == 0)
                        {
                            _engine.ThrowError("Syntax error, missing tokens for argument.", tokens[i]);
                        }

                        buffer.RemoveAt(buffer.Count - 1);

                        arguments.Add(new List <Token>(buffer));
                        buffer.Clear();
                    }

                    // Reached the end of all argument tokens.
                    // All tokens from the start, or from the last ',' token are part of the last argument.
                    if (i == tokens.Count - 1)
                    {
                        // Arguments cannot be empty.
                        if (buffer.Count == 0 && !isFirst)
                        {
                            _engine.ThrowError("Syntax error, missing tokens for argument.", tokens[i]);
                        }

                        arguments.Add(new List <Token>(buffer));
                        buffer.Clear();
                    }
                }
            }
        }
예제 #4
0
        // Checks whether a list of tokens is a valid conditional statement.
        private bool IsConditional(List <Token> tokens)
        {
            var isConditional = false;
            var scopeCheck    = new ScopeCheck();

            for (int i = 0; i < tokens.Count; i++)
            {
                var token = tokens[i];

                scopeCheck.Check(token);

                if (token.Equals("?", TokenTypes.Punctuator) && scopeCheck.IsInScope)
                {
                    isConditional = true;
                    SkipInfo skip = SkipFromTo("?", ":", tokens, i);
                }
            }

            return(isConditional);
        }