From f58ed1c03e67839c5b668f4eda8af77259f6a3b8 Mon Sep 17 00:00:00 2001 From: Seggan Date: Fri, 1 Dec 2023 13:22:52 -0500 Subject: [PATCH] Fix lexer and separate stream wrapping --- .../io/github/seggan/metis/parsing/Lexer.kt | 3 +-- .../io/github/seggan/metis/parsing/Span.kt | 2 +- .../io/github/seggan/metis/runtime/State.kt | 18 ++++++++++++++---- .../metis/runtime/intrinsics/NativeLibrary.kt | 6 +++--- .../metis/runtime/intrinsics/NativeObjects.kt | 14 ++++++-------- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/metis-lang/src/main/kotlin/io/github/seggan/metis/parsing/Lexer.kt b/metis-lang/src/main/kotlin/io/github/seggan/metis/parsing/Lexer.kt index ca79adf..d313acf 100644 --- a/metis-lang/src/main/kotlin/io/github/seggan/metis/parsing/Lexer.kt +++ b/metis-lang/src/main/kotlin/io/github/seggan/metis/parsing/Lexer.kt @@ -88,8 +88,6 @@ object Lexer { matchers.add(TokenMatcher.StringyLiteral('\'', Token.Type.BYTES)) } - private var pos = 0 - /** * Lexes the source code. * @@ -99,6 +97,7 @@ object Lexer { fun lex(source: CodeSource): List { val tokens = mutableListOf() val code = StringBuilder(source.text) + var pos = 0 while (code.isNotEmpty()) { val matched = mutableListOf>() for (matcher in matchers) { diff --git a/metis-lang/src/main/kotlin/io/github/seggan/metis/parsing/Span.kt b/metis-lang/src/main/kotlin/io/github/seggan/metis/parsing/Span.kt index f7364fd..4194204 100644 --- a/metis-lang/src/main/kotlin/io/github/seggan/metis/parsing/Span.kt +++ b/metis-lang/src/main/kotlin/io/github/seggan/metis/parsing/Span.kt @@ -21,7 +21,7 @@ data class Span(val start: Int, val end: Int, val source: CodeSource) { val lines = source.text.split("\n") var pos = start var line = 0 - while (pos > lines[line].length) { + while (line < lines.size && pos > lines[line].length) { pos -= lines[line].length + 1 line++ } diff --git a/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/State.kt b/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/State.kt index ee9fb4c..99830c8 100644 --- a/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/State.kt +++ b/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/State.kt @@ -63,6 +63,16 @@ class State(parentState: State? = null) { */ var currentDir = fileSystem.getPath(System.getProperty("user.dir")).toAbsolutePath() + /** + * The function used to wrap [InputStream]s into Metis objects. + */ + var inStreamWrapper: InputStreamWrapper = InputStreamWrapper { Value.Native(it, inStreamMetatable) } + + /** + * The function used to wrap [OutputStream]s into Metis objects. + */ + var outStreamWrapper: OutputStreamWrapper = OutputStreamWrapper { Value.Native(it, outStreamMetatable) } + internal val openUpvalues = ArrayDeque() private var throwingException: MetisRuntimeException? = null @@ -125,9 +135,9 @@ class State(parentState: State? = null) { } val io = Value.Table() - io["stdout"] = zeroArgFunction { wrapOutStream(stdout) } - io["stderr"] = zeroArgFunction { wrapOutStream(stderr) } - io["stdin"] = zeroArgFunction { wrapInStream(stdin) } + io["stdout"] = zeroArgFunction { outStreamWrapper.wrap(stdout) } + io["stderr"] = zeroArgFunction { outStreamWrapper.wrap(stderr) } + io["stdin"] = zeroArgFunction { inStreamWrapper.wrap(stdin) } io["inStream"] = inStreamMetatable io["outStream"] = outStreamMetatable @@ -148,7 +158,7 @@ class State(parentState: State? = null) { runCode(CodeSource("core") { State::class.java.classLoader.getResource("core.metis")!!.readText() }) for (script in coreScripts) { runCode(CodeSource(script) { - State::class.java.classLoader.getResource("./core/$it.metis")!!.readText() + State::class.java.getResource("/core/$it.metis")!!.readText() }) } diff --git a/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/intrinsics/NativeLibrary.kt b/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/intrinsics/NativeLibrary.kt index 9cb2e33..c845123 100644 --- a/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/intrinsics/NativeLibrary.kt +++ b/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/intrinsics/NativeLibrary.kt @@ -109,7 +109,7 @@ object OsLib : NativeLibrary("os") { */ object PathLib : NativeLibrary("__path") { - private inline fun pathFunction(crossinline fn: (Path) -> Value) = oneArgFunction { self -> + private inline fun pathFunction(crossinline fn: State.(Path) -> Value) = oneArgFunction { self -> translateIoError { fn(toPath(self)) } } @@ -154,8 +154,8 @@ object PathLib : NativeLibrary("__path") { lib["createDir"] = pathFunction { it.createDirectory().absolutePathString().metisValue() } lib["createDirs"] = pathFunction { it.createDirectories().absolutePathString().metisValue() } lib["deleteRecursive"] = pathFunction { it.deleteRecursively(); Value.Null } - lib["openWrite"] = pathFunction { wrapOutStream(it.outputStream()) } - lib["openRead"] = pathFunction { wrapInStream(it.inputStream()) } + lib["openWrite"] = pathFunction { outStreamWrapper.wrap(it.outputStream()) } + lib["openRead"] = pathFunction { inStreamWrapper.wrap(it.inputStream()) } } } diff --git a/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/intrinsics/NativeObjects.kt b/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/intrinsics/NativeObjects.kt index 4dd8c5d..752e883 100644 --- a/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/intrinsics/NativeObjects.kt +++ b/metis-lang/src/main/kotlin/io/github/seggan/metis/runtime/intrinsics/NativeObjects.kt @@ -58,10 +58,9 @@ internal val outStreamMetatable = buildTable { table -> } } -/** - * Wraps an [OutputStream] in a [Value]. - */ -fun wrapOutStream(stream: OutputStream): Value = Value.Native(stream, outStreamMetatable) +fun interface OutputStreamWrapper { + fun wrap(stream: OutputStream): Value +} internal val inStreamMetatable = buildTable { table -> table["read"] = twoArgFunction(true) { self, buffer -> @@ -88,10 +87,9 @@ internal val inStreamMetatable = buildTable { table -> } } -/** - * Wraps an [InputStream] in a [Value]. - */ -fun wrapInStream(stream: InputStream): Value = Value.Native(stream, inStreamMetatable) +fun interface InputStreamWrapper { + fun wrap(stream: InputStream): Value +} private val sbMetatable = buildTable { table -> table["__append"] = twoArgFunction(true) { self, value ->