private static IEnumerable <IToken> Lex(CodeFile file, Diagnostics diagnostics) { var code = file.Code; var text = code.Text; var tokenStart = 0; var tokenEnd = -1; // One past the end position to allow for zero length spans while (tokenStart < text.Length) { var currentChar = text[tokenStart]; switch (currentChar) { case '{': yield return(TokenFactory.OpenBrace(SymbolSpan())); break; case '}': yield return(TokenFactory.CloseBrace(SymbolSpan())); break; case '(': yield return(TokenFactory.OpenParen(SymbolSpan())); break; case ')': yield return(TokenFactory.CloseParen(SymbolSpan())); break; case '[': case ']': case '|': case '&': case '@': case '`': case '$': yield return(NewReservedOperator()); break; case ';': yield return(TokenFactory.Semicolon(SymbolSpan())); break; case ',': yield return(TokenFactory.Comma(SymbolSpan())); break; case '#': switch (NextChar()) { case '#': // it is `##` yield return(NewReservedOperator(2)); break; case '(': // it is `#(` yield return(NewReservedOperator(2)); break; case '[': // it is `#[` yield return(NewReservedOperator(2)); break; case '{': // it is `#{` yield return(NewReservedOperator(2)); break; default: // it is `#` yield return(NewReservedOperator()); break; } break; case '.': if (NextChar() is '.') { if (CharAt(2) is '<') { // it is `..<` yield return(TokenFactory.DotDotLessThan(SymbolSpan(3))); } else { // it is `..` yield return(TokenFactory.DotDot(SymbolSpan(2))); } } else { yield return(TokenFactory.Dot(SymbolSpan())); } break; case ':': if (NextChar() is ':' && CharAt(2) is '.') { // it is `::.` yield return(TokenFactory.ColonColonDot(SymbolSpan(3))); } else { // it is `:` yield return(TokenFactory.Colon(SymbolSpan())); } break;