mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 05:10:55 +00:00
add a standard library, and introduce formed imports (import std "myfile.pork")
This commit is contained in:
@ -0,0 +1,3 @@
|
||||
package gay.pizza.pork.frontend
|
||||
|
||||
data class ImportLocator(val path: String, val form: String? = null)
|
@ -0,0 +1,7 @@
|
||||
package gay.pizza.pork.frontend
|
||||
|
||||
interface ImportSource {
|
||||
val fileContentSource: ContentSource
|
||||
|
||||
fun provideContentSource(form: String): ContentSource
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package gay.pizza.pork.frontend
|
||||
|
||||
class StandardImportSource(override val fileContentSource: ContentSource) : ImportSource {
|
||||
private val providers = mutableMapOf<String,ContentSource>()
|
||||
|
||||
override fun provideContentSource(form: String): ContentSource {
|
||||
return providers[form] ?:
|
||||
throw RuntimeException("Unknown import form: $form")
|
||||
}
|
||||
|
||||
fun addContentSource(form: String, contentSource: ContentSource) {
|
||||
providers[form] = contentSource
|
||||
}
|
||||
}
|
@ -7,37 +7,57 @@ import gay.pizza.pork.parser.Parser
|
||||
import gay.pizza.pork.parser.TokenStreamSource
|
||||
import gay.pizza.pork.parser.Tokenizer
|
||||
|
||||
class World(val contentSource: ContentSource) {
|
||||
class World(val importSource: ImportSource) {
|
||||
private val internalUnits = mutableMapOf<String, CompilationUnit>()
|
||||
|
||||
val units: List<CompilationUnit>
|
||||
get() = internalUnits.values.toList()
|
||||
|
||||
private fun loadOneUnit(path: String): CompilationUnit {
|
||||
val stableIdentity = contentSource.stableContentIdentity(path)
|
||||
val cached = internalUnits[stableIdentity]
|
||||
private fun loadOneUnit(importLocator: ImportLocator): CompilationUnit {
|
||||
val contentSource = pickContentSource(importLocator.form)
|
||||
val stableKey = stableIdentity(importLocator, contentSource = contentSource)
|
||||
val cached = internalUnits[stableKey]
|
||||
if (cached != null) {
|
||||
return cached
|
||||
}
|
||||
val charSource = contentSource.loadAsCharSource(path)
|
||||
val charSource = contentSource.loadAsCharSource(importLocator.path)
|
||||
val tokenizer = Tokenizer(charSource)
|
||||
val tokenStream = tokenizer.tokenize()
|
||||
val parser = Parser(TokenStreamSource(tokenStream), DiscardNodeAttribution)
|
||||
return parser.readCompilationUnit()
|
||||
val unit = parser.readCompilationUnit()
|
||||
internalUnits[stableKey] = unit
|
||||
return unit
|
||||
}
|
||||
|
||||
private fun resolveAllImports(unit: CompilationUnit): Set<CompilationUnit> {
|
||||
val units = mutableSetOf<CompilationUnit>()
|
||||
for (declaration in unit.declarations.filterIsInstance<ImportDeclaration>()) {
|
||||
val importedUnit = loadOneUnit(declaration.path.text)
|
||||
val importLocator = ImportLocator(declaration.path.text, form = declaration.form?.id)
|
||||
val importedUnit = loadOneUnit(importLocator)
|
||||
units.add(importedUnit)
|
||||
}
|
||||
return units
|
||||
}
|
||||
|
||||
fun load(path: String): CompilationUnit {
|
||||
val unit = loadOneUnit(path)
|
||||
fun load(importLocator: ImportLocator): CompilationUnit {
|
||||
val unit = loadOneUnit(importLocator)
|
||||
resolveAllImports(unit)
|
||||
return unit
|
||||
}
|
||||
|
||||
private fun pickContentSource(form: String? = null): ContentSource {
|
||||
if (form != null) {
|
||||
return importSource.provideContentSource(form)
|
||||
}
|
||||
return importSource.fileContentSource
|
||||
}
|
||||
|
||||
fun stableIdentity(
|
||||
importLocator: ImportLocator,
|
||||
contentSource: ContentSource = pickContentSource(importLocator.form)
|
||||
): String {
|
||||
val formKey = importLocator.form ?: "file"
|
||||
val stableIdentity = contentSource.stableContentIdentity(importLocator.path)
|
||||
return "[${formKey}][${stableIdentity}]"
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user