diff --git a/src/Syntax/Lexer.cs b/src/Syntax/Lexer.cs index 269fb98..69fbf80 100644 --- a/src/Syntax/Lexer.cs +++ b/src/Syntax/Lexer.cs @@ -24,7 +24,7 @@ public class Lexer /// The of the current lexing iteration in the script. /// private Position _position; - + /// /// The character in the of the current lexing iteration in the script. /// @@ -92,21 +92,16 @@ private void ReverseTo(int index) { switch (_currentChar) { - case '\r': - case '\t': - case ' ': + case '\r' or '\t' or ' ': Advance(); break; - case ';': - case '\n': + case ';' or '\n': tokens.Add(CompileNewLines()); break; case '@': SkipComment(); break; - case '"': - case '`': - case '\'': + case '"' or '`' or '\'': tokens.Add(CompileStringLike(out EzrSyntaxError? error)); if (error is not null) return error; @@ -236,8 +231,7 @@ private void ReverseTo(int index) tokens.Add(new Token(TokenType.Tilde, TokenTypeGroup.Symbol, string.Empty, _position)); Advance(); break; - case '#': - case '_': + case '#' or '_': case char current when char.IsLetter(current): tokens.Add(CompileIdentifier(out error)); if (error is not null) @@ -275,7 +269,7 @@ private void SkipComment() private Token CompileNumber() { Position startPosition = _position; - bool hasPeriod = false; + bool isFloat = false; while (!_reachedEnd && (char.IsDigit(_currentChar) || _currentChar == '.')) { @@ -284,17 +278,17 @@ private Token CompileNumber() int peekIndex = _position.Index + 1; char next = peekIndex < _script.Length ? _script[peekIndex] : '\0'; - if (hasPeriod || !char.IsDigit(next)) + if (isFloat || !char.IsDigit(next)) break; - hasPeriod = true; + isFloat = true; } Advance(); } return new Token( - hasPeriod ? TokenType.FloatingPoint : TokenType.Integer, + isFloat ? TokenType.FloatingPoint : TokenType.Integer, TokenTypeGroup.Value, _script[startPosition.Index.._position.Index], startPosition, @@ -349,15 +343,15 @@ private Token CompileStringLike(out EzrSyntaxError? error) { if (_currentChar == '\\') { - ProcessEscapeSequence(toReturn, ref error); + ProcessEscapeSequence(toReturn, out error); if (error is not null) return Token.Empty; + + continue; } - else - { - toReturn.Append(_currentChar); - Advance(); - } + + toReturn.Append(_currentChar); + Advance(); } if (_currentChar != enclosingChar) @@ -395,18 +389,19 @@ private Token CompileStringLike(out EzrSyntaxError? error) /// /// The to append the special character to. /// Any that occurred in the process; if none occurred. - private void ProcessEscapeSequence(StringBuilder builder, ref EzrSyntaxError? error) + private void ProcessEscapeSequence(StringBuilder builder, out EzrSyntaxError? error) { + error = null; Position startPosition = _position; Advance(); switch (_currentChar) { case 'u': - builder.Append(ProcessUtf16Sequence(ref error)); + builder.Append(ProcessUtf16Sequence(out error)); break; case 'U': - builder.Append(ProcessUtf32Sequence(ref error)); + builder.Append(ProcessUtf32Sequence(out error)); break; case 'n': builder.Append('\n'); @@ -436,10 +431,7 @@ private void ProcessEscapeSequence(StringBuilder builder, ref EzrSyntaxError? er builder.Append('\v'); Advance(); break; - case '"': - case '\'': - case '`': - case '\\': + case '"' or '\'' or '`' or '\\': builder.Append(_currentChar); Advance(); break; @@ -454,12 +446,15 @@ private void ProcessEscapeSequence(StringBuilder builder, ref EzrSyntaxError? er /// /// Any that occurred in the process; if none occurred. /// The UTF-16 character. - private char[] ProcessUtf16Sequence(ref EzrSyntaxError? error) + private char[] ProcessUtf16Sequence(out EzrSyntaxError? error) { + const int Utf16SequenceLength = 4; + + error = null; Advance(); Position startPosition = _position; - for (int i = 0; i < 4; i++) + for (int i = 0; i < Utf16SequenceLength; i++) { if (_currentChar is (not >= 'a' or not <= 'f') and (not >= 'A' or not <= 'F') and (not >= '0' or not <= '9')) { @@ -470,7 +465,10 @@ private char[] ProcessUtf16Sequence(ref EzrSyntaxError? error) Advance(); } - return Encoding.Unicode.GetChars([Convert.ToByte(_script[(startPosition.Index + 2).._position.Index], 16), Convert.ToByte(_script[startPosition.Index..(_position.Index - 2)], 16)]); + string upper = _script[(startPosition.Index + 2).._position.Index]; + string lower = _script[startPosition.Index..(_position.Index - 2)]; + + return Encoding.Unicode.GetChars([Convert.ToByte(upper, 16), Convert.ToByte(lower, 16)]); } /// @@ -478,12 +476,15 @@ private char[] ProcessUtf16Sequence(ref EzrSyntaxError? error) /// /// Any that occurred in the process; if none occurred. /// The UTF-32 character. - private string ProcessUtf32Sequence(ref EzrSyntaxError? error) + private string ProcessUtf32Sequence(out EzrSyntaxError? error) { + const int Utf32SequenceLength = 4; + + error = null; Advance(); Position startPosition = _position; - for (int i = 0; i < 6; i++) + for (int i = 0; i < Utf32SequenceLength; i++) { if (_currentChar is (not >= 'a' or not <= 'f') and (not >= 'A' or not <= 'F') and (not >= '0' or not <= '9')) { @@ -569,7 +570,7 @@ private Token CompileIdentifier(out EzrSyntaxError? error) Advance(); if (!char.IsLetterOrDigit(_currentChar) && _currentChar != '_') { - error = new EzrSyntaxError(EzrSyntaxError.UnexpectedCharacter, "The hash symbol should only be used before identifiers to escape keyword detection.", startPosition, _position); + error = new EzrSyntaxError(EzrSyntaxError.UnexpectedCharacter, "The hash (#) symbol should only be used before identifiers to escape keyword detection.", startPosition, _position); return Token.Empty; } }