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 } }
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); }
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)); }
// 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); }
// 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); }
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); }
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)); } }
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); }
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); }
// 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());
private IExpression ParseIdentifier(IPeekableEnumerator <Token> tokens) { return(new Identifier(tokens.Current.Literal)); }