feat(lexer): Parentheses and quoted strings
This commit is contained in:
parent
e1f632ca40
commit
dc9e43e9ba
4 changed files with 155 additions and 23 deletions
|
@ -10,7 +10,10 @@ class Lexer(private val source: String) {
|
|||
while (hasNext()) {
|
||||
val char: Char = peek()
|
||||
tokens += when {
|
||||
char == '.' -> scanDot()
|
||||
char == '(' -> scanSymbol(TokenType.LEFT_PARENTHESES)
|
||||
char == ')' -> scanSymbol(TokenType.RIGHT_PARENTHESES)
|
||||
char == '.' -> scanSymbol(TokenType.DOT)
|
||||
char == '"' -> scanQuotedString()
|
||||
char.isLetterOrDigit() -> scanAlphanumeric()
|
||||
char.isWhitespace() -> { scanWhitespace(); continue }
|
||||
else -> throw Error("Unknown symbol: $char", position)
|
||||
|
@ -45,26 +48,39 @@ class Lexer(private val source: String) {
|
|||
|
||||
// Scanners
|
||||
|
||||
private fun scanDot(): Token {
|
||||
return Token(TokenType.DOT, next().toString(), getPosition(1))
|
||||
private fun scanSymbol(tokenType: TokenType): Token {
|
||||
return Token(tokenType, next().toString(), getPosition(1))
|
||||
}
|
||||
|
||||
private fun scanAlphanumeric(): Token {
|
||||
var length = 0
|
||||
var value = ""
|
||||
|
||||
while (hasNext() && peek().isLetterOrDigit()) {
|
||||
value += next()
|
||||
next()
|
||||
length++
|
||||
}
|
||||
val value = source.substring(position.offset - length, position.offset)
|
||||
return Token(TokenType.ALPHANUMERIC, value, getPosition(length))
|
||||
}
|
||||
|
||||
private fun scanQuotedString(): Token {
|
||||
if (next() != '"') {
|
||||
throw Error("Illegal state: Expected opening quote", position)
|
||||
}
|
||||
var length = 0
|
||||
while (hasNext() && peek() != '"') {
|
||||
next()
|
||||
length++
|
||||
}
|
||||
if (next() != '"') {
|
||||
throw Error("Illegal state: Expected closing quote", position)
|
||||
}
|
||||
val value = source.substring(position.offset - length - 1, position.offset - 1)
|
||||
return Token(TokenType.ALPHANUMERIC, value, getPosition(length))
|
||||
}
|
||||
|
||||
private fun scanWhitespace() {
|
||||
while (hasNext() && peek().isWhitespace()) {
|
||||
val char = next()
|
||||
if (char == '\n') {
|
||||
if (next() == '\n') {
|
||||
position.line++
|
||||
position.column = 0
|
||||
}
|
||||
|
|
Reference in a new issue