<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/main/lex.go
diff options
context:
space:
mode:
Diffstat (limited to 'main/lex.go')
-rw-r--r--main/lex.go233
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
-}