diff --git a/ast/build.gradle.kts b/ast/build.gradle.kts index a60342f..0b4790c 100644 --- a/ast/build.gradle.kts +++ b/ast/build.gradle.kts @@ -2,3 +2,7 @@ plugins { id("gay.pizza.pork.module") id("gay.pizza.pork.ast") } + +tasks.compileKotlin { + dependsOn(tasks.generateAstCode) +} diff --git a/buildext/build.gradle.kts b/buildext/build.gradle.kts index 7308b9d..1162b00 100644 --- a/buildext/build.gradle.kts +++ b/buildext/build.gradle.kts @@ -33,5 +33,13 @@ gradlePlugin { displayName = "Pork Module" description = "Module convention for pork" } + + create("pork_stdlib") { + id = "gay.pizza.pork.stdlib" + implementationClass = "gay.pizza.pork.buildext.PorkStdlibPlugin" + + displayName = "Pork Stdlib" + description = "Stdlib generation code for pork" + } } } diff --git a/buildext/src/main/kotlin/gay/pizza/pork/buildext/GenerateAstCode.kt b/buildext/src/main/kotlin/gay/pizza/pork/buildext/GenerateAstCode.kt index e847279..433e341 100644 --- a/buildext/src/main/kotlin/gay/pizza/pork/buildext/GenerateAstCode.kt +++ b/buildext/src/main/kotlin/gay/pizza/pork/buildext/GenerateAstCode.kt @@ -15,10 +15,6 @@ import kotlin.io.path.deleteIfExists import kotlin.io.path.writeText open class GenerateAstCode : DefaultTask() { - init { - outputs.upToDateWhen { false } - } - @get:InputFile var astDescriptionFile: File = project.file("src/main/ast/pork.yml") diff --git a/buildext/src/main/kotlin/gay/pizza/pork/buildext/GenerateStdlibManifest.kt b/buildext/src/main/kotlin/gay/pizza/pork/buildext/GenerateStdlibManifest.kt new file mode 100644 index 0000000..83c8f63 --- /dev/null +++ b/buildext/src/main/kotlin/gay/pizza/pork/buildext/GenerateStdlibManifest.kt @@ -0,0 +1,34 @@ +package gay.pizza.pork.buildext + +import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import java.io.File +import kotlin.io.path.deleteIfExists +import kotlin.io.path.writeText + +open class GenerateStdlibManifest : DefaultTask() { + @get:InputDirectory + val porkStdlibCode: File = project.file("src/main/pork") + + @get:OutputFile + val stdlibManifestFile: Provider = + project.layout.buildDirectory.file("generated/pork/stdlib.manifest") + + @TaskAction + fun generate() { + val files = porkStdlibCode.walkTopDown().mapNotNull { file -> + if (!file.isFile || !file.name.endsWith(".pork")) { + null + } else { + file.relativeTo(porkStdlibCode).path + } + } + val manifestFilePath = stdlibManifestFile.get().asFile.toPath() + manifestFilePath.deleteIfExists() + manifestFilePath.writeText(files.joinToString("\n") + "\n") + } +} diff --git a/buildext/src/main/kotlin/gay/pizza/pork/buildext/PorkAstPlugin.kt b/buildext/src/main/kotlin/gay/pizza/pork/buildext/PorkAstPlugin.kt index 931baa0..6659f4a 100644 --- a/buildext/src/main/kotlin/gay/pizza/pork/buildext/PorkAstPlugin.kt +++ b/buildext/src/main/kotlin/gay/pizza/pork/buildext/PorkAstPlugin.kt @@ -2,9 +2,15 @@ package gay.pizza.pork.buildext import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.create class PorkAstPlugin : Plugin { override fun apply(target: Project) { - target.tasks.create("generateAstCode", GenerateAstCode::class.java) + val generateAstCode = createGenerateAstCode(target) + val processResources = target.tasks.getByName("processResources") + processResources.dependsOn(generateAstCode) } + + private fun createGenerateAstCode(project: Project): GenerateAstCode = + project.tasks.create("generateAstCode", GenerateAstCode::class) } diff --git a/buildext/src/main/kotlin/gay/pizza/pork/buildext/PorkStdlibPlugin.kt b/buildext/src/main/kotlin/gay/pizza/pork/buildext/PorkStdlibPlugin.kt new file mode 100644 index 0000000..c0f8edd --- /dev/null +++ b/buildext/src/main/kotlin/gay/pizza/pork/buildext/PorkStdlibPlugin.kt @@ -0,0 +1,16 @@ +package gay.pizza.pork.buildext + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.create + +class PorkStdlibPlugin : Plugin { + override fun apply(target: Project) { + val generateStdlibManifest = createGenerateStdlibManifest(target) + val processResources = target.tasks.getByName("processResources") + processResources.dependsOn(generateStdlibManifest) + } + + private fun createGenerateStdlibManifest(project: Project): GenerateStdlibManifest = + project.tasks.create("generateStdlibManifest", GenerateStdlibManifest::class) +} diff --git a/stdlib/build.gradle.kts b/stdlib/build.gradle.kts index e3b1be3..cac9864 100644 --- a/stdlib/build.gradle.kts +++ b/stdlib/build.gradle.kts @@ -1,11 +1,19 @@ plugins { id("gay.pizza.pork.module") + id("gay.pizza.pork.stdlib") } tasks.processResources { + dependsOn(tasks.generateStdlibManifest) + inputs.file(tasks.generateStdlibManifest.get().stdlibManifestFile) + from("src/main/pork") { into("pork/stdlib") } + + from(tasks.generateStdlibManifest.get().outputs) { + into("pork") + } } dependencies { diff --git a/stdlib/src/main/kotlin/gay/pizza/pork/stdlib/PorkStdlib.kt b/stdlib/src/main/kotlin/gay/pizza/pork/stdlib/PorkStdlib.kt index e9d2cda..240aa80 100644 --- a/stdlib/src/main/kotlin/gay/pizza/pork/stdlib/PorkStdlib.kt +++ b/stdlib/src/main/kotlin/gay/pizza/pork/stdlib/PorkStdlib.kt @@ -8,7 +8,7 @@ object PorkStdlib : ContentSource { private val stdlibClass = PorkStdlib::class.java private fun readManifestFiles(): List { - val manifestContent = read("stdlib.manifest", check = false) + val manifestContent = read("stdlib.manifest") return manifestContent.split("\n").filter { line -> val trimmed = line.trim() trimmed.isNotEmpty() && !trimmed.startsWith("#") @@ -17,17 +17,21 @@ object PorkStdlib : ContentSource { val files: List = readManifestFiles() - private fun read(path: String, check: Boolean = true): String { - if (check && !files.contains(path)) { + private fun readPorkFile(path: String): String { + if (!files.contains(path)) { throw RuntimeException("Stdlib does not contain file '${path}'") } - val stream = stdlibClass.getResourceAsStream("/pork/stdlib/${path}") - ?: throw RuntimeException("Stdlib does not contain file '${path}'") + return read("stdlib/${path}") + } + + private fun read(path: String): String { + val stream = stdlibClass.getResourceAsStream("/pork/${path}") + ?: throw RuntimeException("Unable to find file '${path}'") return String(stream.readAllBytes()) } override fun loadAsCharSource(path: String): CharSource { - return StringCharSource(read(path)) + return StringCharSource(readPorkFile(path)) } override fun stableContentIdentity(path: String): String { diff --git a/stdlib/src/main/pork/stdlib.manifest b/stdlib/src/main/pork/stdlib.manifest deleted file mode 100644 index f673d07..0000000 --- a/stdlib/src/main/pork/stdlib.manifest +++ /dev/null @@ -1,3 +0,0 @@ -lang/prelude.pork -ffi/malloc.pork -numerics/operator.pork