private void CompareListToPeekableEnumerator(List <string> list, IPeekableEnumerator <string> enumerator)
        {
            Assert.AreEqual(list[0], enumerator.PeekNext);
            Assert.IsNull(enumerator.Current);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(list[0], enumerator.Current);
            Assert.AreEqual(list[0], ((IEnumerator)enumerator).Current);
            Assert.AreEqual(list[1], enumerator.PeekNext);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(list[2], enumerator.PeekNext);
            Assert.AreEqual(list[1], enumerator.Current);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsNull(enumerator.PeekNext);
            Assert.AreEqual(list[2], enumerator.Current);
            Assert.IsFalse(enumerator.MoveNext());
            Assert.IsNull(enumerator.Current);
            Assert.IsNull(enumerator.PeekNext);

            try
            {
                enumerator.Reset();
                Assert.IsNull(enumerator.Current);
                Assert.AreEqual(list[0], enumerator.PeekNext);
                Assert.IsTrue(enumerator.MoveNext());
                Assert.AreEqual(list[0], enumerator.Current);
            }
            catch (System.NotSupportedException)
            {
                // ignore if enumerator.Reset() is unavailable
            }
        }
Beispiel #2
0
        private IStatement ParseLetStatement(IPeekableEnumerator <Token> tokens)
        {
            if (ExpectTokenAndAdvance(tokens, Token.Tokens.Let) == null)
            {
                return(null);
            }

            var identifierToken = ExpectTokenAndAdvance(tokens, Token.Tokens.Ident);

            if (identifierToken == null)
            {
                return(null);
            }
            var identifier = new Identifier(identifierToken.Literal);

            if (ExpectTokenAndAdvance(tokens, Token.Tokens.Assign) == null)
            {
                return(null);
            }

            // TODO: parse expression
            while (tokens.MoveNext())
            {
                if (tokens.Current.Type == Token.Tokens.Semicolon)
                {
                    return(new LetStatement(identifier, null));
                }
            }

            return(null);
        }
Beispiel #3
0
        private IExpression ParseIntegerLiteral(IPeekableEnumerator <Token> tokens)
        {
            var inputString = tokens.Current.Literal;

            if (!int.TryParse(inputString, out int value))
            {
                OnParserError($"{inputString} is not a valid integer.");
                return(null);
            }
            return(new IntegerLiteral(value));
        }
Beispiel #4
0
        // ReSharper disable once UnusedParameter.Local
        public IExpression ParseExpression(IPeekableEnumerator <Token> tokens, Precedence precedence)
        {
            if (!_prefixParserFns.TryGetValue(tokens.Current.Type, out var prefix))
            {
                return(null);
            }

            var leftExp = prefix(tokens);

            return(leftExp);
        }
Beispiel #5
0
        // ReSharper disable once UnusedMember.Local
        private bool ExpectNextToken(IPeekableEnumerator <Token> tokens, Token.Tokens ident)
        {
            if (tokens.PeekNext?.Type != ident)
            {
                AddError(string.Format("expected {0}, got {1} instead",
                                       ident,
                                       tokens.PeekNext?.ToString() ?? "<EOF>"));
                return(false);
            }

            return(true);
        }
Beispiel #6
0
        private Token ExpectTokenAndAdvance(IPeekableEnumerator <Token> tokens, Token.Tokens ident)
        {
            var currentToken = tokens.Current;

            if (currentToken?.Type != ident)
            {
                AddError(string.Format("expected {0}, got {1} instead",
                                       ident,
                                       currentToken?.ToString() ?? "<EOF>"));
                return(null);
            }

            tokens.MoveNext();
            return(currentToken);
        }
Beispiel #7
0
        private IStatement ParseStatement(IPeekableEnumerator <Token> tokens)
        {
            switch (tokens.Current?.Type)
            {
            case null:
                return(null);

            case Token.Tokens.Let:
                return(ParseLetStatement(tokens));

            case Token.Tokens.Return:
                return(ParseReturnStatement(tokens));

            default:
                return(ParseExpressionStatement(tokens));
            }
        }
Beispiel #8
0
        private IStatement ParseExpressionStatement(IPeekableEnumerator <Token> tokens)
        {
            var expression = _expressionParser.ParseExpression(tokens, Precedence.Lowest);

            if (expression == null)
            {
                return(null);
            }

            var statement = new ExpressionStatement(expression);

            if (tokens.PeekNext?.Type == Token.Tokens.Semicolon)
            {
                tokens.MoveNext();
            }

            return(statement);
        }
Beispiel #9
0
        private IStatement ParseReturnStatement(IPeekableEnumerator <Token> tokens)
        {
            if (ExpectTokenAndAdvance(tokens, Token.Tokens.Return) == null)
            {
                return(null);
            }

            // TODO: parse expression
            while (tokens.MoveNext())
            {
                if (tokens.Current.Type == Token.Tokens.Semicolon)
                {
                    return(new ReturnStatement(null));
                }
            }

            return(null);
        }
Beispiel #10
0
//        public string Remaining()
//        {
//            var tokens = new StringBuilder();
//            foreach (var token in this)
//            {
//                tokens.Append(' ').Append(token);
//            }
//
//            return tokens.Length == 0 ? "" : tokens.ToString().Substring(1); // remove first space
//        }
//
//        public StringTokenizer Clone()
//        {
//            return !_isMoveNext
//                ? new StringTokenizer(_source, Enumerable.Empty<(int, string)>())
//                : Tokenize(_source.Substring(_with.Current.index));
//        }

        // IEnumerator.Reset (not a delegate implementation)
        public void Reset() => _with = new PeekEnumerator <string>(_provider.GetEnumerator());
Beispiel #11
0
 private IExpression ParseIdentifier(IPeekableEnumerator <Token> tokens)
 {
     return(new Identifier(tokens.Current.Literal));
 }