Add import binding data for module slot seeding

This commit is contained in:
Sergey Chernov 2026-02-08 12:56:24 +03:00
parent 40a55f298e
commit a557d0cc59
2 changed files with 60 additions and 1 deletions

View File

@ -0,0 +1,28 @@
/*
* Copyright 2026 Sergey S. Chernov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sergeych.lyng
sealed class ImportBindingSource {
data class Module(val name: String, val pos: Pos) : ImportBindingSource()
object Root : ImportBindingSource()
object Seed : ImportBindingSource()
}
data class ImportBinding(
val symbol: String,
val source: ImportBindingSource,
)

View File

@ -33,6 +33,7 @@ class Script(
override val pos: Pos, override val pos: Pos,
private val statements: List<Statement> = emptyList(), private val statements: List<Statement> = emptyList(),
private val moduleSlotPlan: Map<String, Int> = emptyMap(), private val moduleSlotPlan: Map<String, Int> = emptyMap(),
private val importBindings: Map<String, ImportBinding> = emptyMap(),
// private val catchReturn: Boolean = false, // private val catchReturn: Boolean = false,
) : Statement() { ) : Statement() {
@ -48,7 +49,11 @@ class Script(
return lastResult return lastResult
} }
private fun seedModuleSlots(scope: Scope) { private suspend fun seedModuleSlots(scope: Scope) {
if (importBindings.isNotEmpty()) {
seedImportBindings(scope)
return
}
val parent = scope.parent ?: return val parent = scope.parent ?: return
for (name in moduleSlotPlan.keys) { for (name in moduleSlotPlan.keys) {
if (scope.objects.containsKey(name)) { if (scope.objects.containsKey(name)) {
@ -70,6 +75,32 @@ class Script(
} }
} }
private suspend fun seedImportBindings(scope: Scope) {
val provider = scope.currentImportProvider
for ((name, binding) in importBindings) {
val record = when (val source = binding.source) {
is ImportBindingSource.Module -> {
val module = provider.prepareImport(source.pos, source.name, null)
module.objects[binding.symbol]?.takeIf { it.visibility.isPublic }
?: scope.raiseSymbolNotFound("symbol ${source.name}.${binding.symbol} not found")
}
ImportBindingSource.Root -> {
provider.rootScope.objects[binding.symbol]?.takeIf { it.visibility.isPublic }
?: scope.raiseSymbolNotFound("symbol ${binding.symbol} not found")
}
ImportBindingSource.Seed -> {
findSeedRecord(scope, binding.symbol)
?: scope.raiseSymbolNotFound("symbol ${binding.symbol} not found")
}
}
if (name == "Exception" && record.value !is ObjClass) {
scope.updateSlotFor(name, ObjRecord(ObjException.Root, isMutable = false))
} else {
scope.updateSlotFor(name, record)
}
}
}
private fun findSeedRecord(scope: Scope?, name: String): ObjRecord? { private fun findSeedRecord(scope: Scope?, name: String): ObjRecord? {
var s = scope var s = scope
var hops = 0 var hops = 0