Skip to content

Commit

Permalink
task processor, add locations to parser combinator
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander.nutz committed Apr 3, 2024
1 parent 5654609 commit 25086a3
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 12 deletions.
70 changes: 70 additions & 0 deletions src/main/kotlin/blitz/async/Processor.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package blitz.async

import blitz.collections.SynchronizedList
import blitz.logic.then

abstract class Processor {
protected val tasks = SynchronizedList(mutableListOf<Task>())


fun tick() {
for (task in tasks) {
if (task.counter >= task.priority) {
task.fn()
task.counter = 0
} else {
task.counter ++
}
}
}

abstract fun add(task: Task)

abstract fun remove(task: Task)

/** priority 0 means every tick; 1 means every second tick; 2 means every third tick, ... */
data class Task(
internal val priority: Int = 0, // every tick
internal val fn: () -> Unit
) {
internal var counter: Int = 0
}

companion object {
fun singleThread(): Processor =
SingleThreadProcessor()

fun manualTick(): Processor =
object : Processor() {
override fun add(task: Task) {
tasks.add(task)
}

override fun remove(task: Task) {
tasks.remove(task)
}
}
}
}

internal class SingleThreadProcessor: Processor() {
private fun createThread() = Thread { while (true) { tick() } }

private var thread: Thread? = null

override fun add(task: Task) {
tasks.add(task)
if (thread == null) {
thread = createThread()
thread!!.start()
}
}

override fun remove(task: Task) {
tasks.remove(task)
tasks.isEmpty().then {
runCatching { thread?.interrupt() }
thread = null
}
}
}
28 changes: 16 additions & 12 deletions src/main/kotlin/blitz/parse/comb/Parser.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package blitz.parse.comb

import blitz.str.collectToString
import kotlin.math.max

@JvmInline
value class Parsable(
val str: String
data class Parsable(
val str: String,
val loc: Int? = null
)

typealias Parser<T> = (Parsable) -> Pair<Parsable, T>?
Expand All @@ -26,21 +25,24 @@ infix fun <T> Parser<T>.or(other: Parser<T>): Parser<T> = {
}

fun Parsable.spaces(): Parsable {
return Parsable(str.trimStart(' '))
val new = str.trimStart(' ')
return Parsable(new, loc?.let { it + str.length - new.length })
}

fun Parsable.whitespaces(): Parsable {
return Parsable(str.trimStart())
val new = str.trimStart()
return Parsable(new, loc?.let { it + str.length - new.length })
}

fun Parsable.require(what: String): Parsable? {
if (str.startsWith(what))
return Parsable(str.substring(what.length))
return Parsable(str.substring(what.length), loc?.let { it + what.length })
return null
}

fun <T> Parsable.untilRequire(c: String, map: (String) -> T?): Pair<Parsable, T>? {
return map(str.substringBefore(c))?.let { Parsable(str.substringAfter(c)) to it }
val before = str.substringBefore(c)
return map(before)?.let { Parsable(str.substringAfter(c), loc?.let { it + before.length }) to it }
}

fun <T> Parsable.asLongAs(vararg li: Char, map: (String) -> T?): Pair<Parsable, T>? {
Expand All @@ -52,7 +54,7 @@ fun <T> Parsable.asLongAs(vararg li: Char, map: (String) -> T?): Pair<Parsable,
break
}
val out = str.substring(o.size)
return map(o.iterator().collectToString())?.let { Parsable(out) to it }
return map(o.iterator().collectToString())?.let { Parsable(out, loc?.plus(o.size)) to it }
}

fun <T> Parsable.map(parser: Parser<T>): Pair<Parsable, T>? =
Expand Down Expand Up @@ -89,17 +91,19 @@ fun <T> Pair<Parsable, T>.require(what: String): Pair<Parsable, T>? =
fun <T> Parsable.array(sep: String, map: (Parsable) -> Pair<Parsable, T>?): Pair<Parsable, List<T>> {
val out = mutableListOf<T>()

var loc = loc
var curr = str
fun step() =
map(Parsable(curr))?.also {
map(Parsable(curr, loc))?.also {
curr = it.first.str
loc = it.first.loc
}

while (true) {
val r = step() ?: break
out.add(r.second)
curr = (Parsable(curr).require(sep) ?: break).str
curr = (Parsable(curr, loc).require(sep) ?: break).str
}

return Parsable(curr) to out
return Parsable(curr, loc) to out
}

0 comments on commit 25086a3

Please sign in to comment.