69 lines
1.7 KiB
Kotlin
69 lines
1.7 KiB
Kotlin
package net.sergeych.ling
|
|
|
|
data class Pos(val source: Source, val line: Int, val column: Int) {
|
|
override fun toString(): String {
|
|
return "${source.fileName}:${line+1}:${column}"
|
|
}
|
|
|
|
fun back(): Pos =
|
|
if( column > 0) Pos(source, line, column-1)
|
|
else if( line > 0) Pos(source, line-1, source.lines[line-1].length - 1)
|
|
else throw IllegalStateException("can't go back from line 0, column 0")
|
|
|
|
val currentLine: String get() = if( end ) "EOF" else source.lines[line]
|
|
|
|
val end: Boolean get() = line >= source.lines.size
|
|
|
|
companion object {
|
|
val builtIn = Pos(Source.builtIn, 0, 0)
|
|
}
|
|
|
|
}
|
|
|
|
class MutablePos(private val from: Pos) {
|
|
|
|
val lines = from.source.lines
|
|
var line = from.line
|
|
private set
|
|
var column = from.column
|
|
private set
|
|
|
|
val end: Boolean get() =
|
|
line == lines.size
|
|
|
|
fun toPos(): Pos = Pos(from.source, line, column)
|
|
|
|
fun advance(): Char? {
|
|
if (end) return null
|
|
val current = lines[line]
|
|
return if (column < current.length) {
|
|
column++
|
|
currentChar
|
|
} else {
|
|
column = 0
|
|
if(++line >= lines.size) null
|
|
else currentChar
|
|
}
|
|
}
|
|
|
|
fun back() {
|
|
if (column > 0) column--
|
|
else if (line > 0)
|
|
column = lines[--line].length - 1
|
|
else throw IllegalStateException("can't go back from line 0, column 0")
|
|
}
|
|
val currentChar: Char
|
|
get() {
|
|
if (end) return 0.toChar()
|
|
val current = lines[line]
|
|
return if (column >= current.length) '\n'
|
|
else current[column]
|
|
}
|
|
|
|
override fun toString() = "($line:$column)"
|
|
|
|
init {
|
|
if( lines[0].isEmpty()) advance()
|
|
}
|
|
}
|