diff options
Diffstat (limited to 'main/lex.go')
-rw-r--r-- | main/lex.go | 233 |
1 files changed, 4 insertions, 229 deletions
diff --git a/main/lex.go b/main/lex.go index 02dd0ee..e93e42a 100644 --- a/main/lex.go +++ b/main/lex.go @@ -113,7 +113,6 @@ type TokenType int const ( TokenErr TokenType = iota // Lexing error TokenEOF // end of file - TokenSemicolon // ; TokenLParen // ( TokenRParen // ) TokenLBrace // { @@ -198,88 +197,24 @@ func isStringIndexChar(r rune) bool { func lexCommand(l *lexer) stateFunc { l.acceptAll(whitespace) l.ignore() - if l.peek() == eof { - l.emit(TokenEOF) - return nil - } r := l.next() switch r { - case '#': - l.emit(TokenHash) - lexPatternStringIndex(l) - return lexCommand - case '@': - l.emit(TokenAt) - lexPatternIntegerIndex(l) - return lexCommand - case '.': - l.emit(TokenDot) - return lexCommand - case '*': - l.emit(TokenAst) - return lexCommand - case '|': - if l.accept("|") { - l.emit(TokenOr) - } else { - l.emit(TokenBar) - } - return lexCommand - case '[': - l.emit(TokenLBrack) - return lexCommand - case ']': - l.emit(TokenRBrack) - return lexCommand - case '(': - l.emit(TokenLParen) - return lexCommand - case ')': - l.emit(TokenRParen) - return lexCommand - case '?': - l.emit(TokenQuestion) - return lexCommand + case eof: + l.emit(TokenEOF) + return nil case '{': l.emit(TokenLBrace) return lexCommand case '}': l.emit(TokenRBrace) - return lexCommandEnd - case '&': - if l.accept("&") { - l.emit(TokenAnd) - return lexCommand - } - case '^': - if l.accept("$") { - l.emit(TokenHatDollar) - } else { - l.emit(TokenHat) - } - return lexCommand - case '$': - l.emit(TokenDollar) - return lexCommand - case '!': - l.emit(TokenExclamation) - return lexCommand - case '~': - l.emit(TokenTilde) return lexCommand - case 'i': - l.emit(TokenCommand) - return lexMultipleLiterals case 's': l.emit(TokenCommand) return lexSubstitution - case 'S': - l.emit(TokenCommand) - return lexBigSubstitution } if isAlpha(r) { l.emit(TokenCommand) - return lexCommandEnd + return lexCommand } return l.errorf("Expected command found something else") } @@ -306,163 +241,3 @@ func lexSubstitution(l *lexer) stateFunc { } return lexCommand } - -func lexBigSubstitution(l *lexer) stateFunc { - delimiter := l.next() - if delimiter == eof || isAlphaNumeric(delimiter) { - return l.errorf("Invalid delimiter for big substitution") - } - l.emit(TokenSubstituteDelimiter) - loop: for { - r := l.next() - switch r { - case delimiter: - l.emit(TokenSubstituteDelimiter) - break loop - case '#': - l.emit(TokenHash) - lexPatternStringIndex(l) - case '@': - l.emit(TokenAt) - lexPatternIntegerIndex(l) - case '.': - l.emit(TokenDot) - case '*': - l.emit(TokenAst) - case '|': - l.emit(TokenBar) - case '[': - l.emit(TokenLBrack) - case ']': - l.emit(TokenRBrack) - case '?': - l.emit(TokenQuestion) - case ':': - l.emit(TokenColon) - case ',': - l.emit(TokenComma) - } - } - loop2: for { - r := l.next() - switch r { - case delimiter: - l.emit(TokenSubstituteDelimiter) - break loop2 - case '\\': - if !l.acceptPassing(isDigit) { - return l.errorf("Expected digit after \\") - } - l.emit(TokenSubstitutePlaceholder) - } - } - // TODO: No clue where I was going with this - return lexCommand -} - -func lexMultipleLiterals(l *lexer) stateFunc { - l.acceptAll(whitespaceNewlines) - l.ignore() - r := l.next() - switch r { - case ';', eof: - l.backup() - return lexCommandEnd - case ':': - l.emit(TokenColon) - return lexMultipleLiterals - case ',': - l.emit(TokenComma) - return lexMultipleLiterals - } - err := lexSingleLiteral(l) - if err != "" { - return l.errorf(err) - } - return lexMultipleLiterals -} - -func lexSingleLiteral(l *lexer) string { - l.acceptAll(whitespaceNewlines) - l.ignore() - r := l.next() - switch r { - case '"': - l.emit(TokenDoubleQuote) - if !lexStringLiteral(l) { - return "Expected closing \"" - } - case 'n': - if !l.expect("ull") { - return "Invalid literal, expected null" - } - l.emit(TokenNullLiteral) - case 't': - if !l.expect("rue") { - return "Invalid literal, expected true" - } - l.emit(TokenTrueLiteral) - case 'f': - if !l.expect("alse") { - return "Invalid literal, expected false" - } - l.emit(TokenFalseLiteral) - case '{', '}', '[', ']': - l.emit(TokenTerminalLiteral) - default: - if isDigit(r) { - lexNumberLiteral(l) - return "" - } - return "Invalid literal" - } - return "" -} - -// Just read the first digit -func lexNumberLiteral(l *lexer) { - l.acceptAllPassing(isDigit) - if l.accept(".") { - l.acceptAllPassing(isDigit) - } - l.emit(TokenNumberLiteral) -} - -// TODO: escape characters -func lexStringLiteral(l *lexer) bool { - for { - r := l.next() - switch r { - case '"': - l.backup() - l.emit(TokenStringLiteral) - l.next() - l.emit(TokenDoubleQuote) - return true - case eof: - return false - } - } -} - -func lexPatternStringIndex(l *lexer) { - l.acceptAllPassing(isStringIndexChar) - l.emit(TokenPatternStringIndex) -} - -func lexPatternIntegerIndex(l *lexer) { - l.acceptAllPassing(isDigit) - l.emit(TokenPatternIntegerIndex) -} - -func lexCommandEnd(l *lexer) stateFunc { - if l.peek() == eof { - l.emit(TokenEOF) - return nil - } - if l.accept("}") { - l.emit(TokenRBrace) - return lexCommandEnd - } - return lexCommand -} |