diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f65512ca..ac2ba24f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,6 +19,7 @@ libfreenect = "0.5.7-1.5.9" librealsense = "2.53.1-1.5.9" gson = "2.10.1" antlr = "4.13.1" +antlrKotlin = "0.1.0-RC14" tensorflow = "0.5.0" minim = "2.2.2" netty = "4.1.92.Final" @@ -76,6 +77,7 @@ javaosc-core = { group = "com.illposed.osc", name = "javaosc-core", version.ref gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } antlr-core = { group = "org.antlr", name = "antlr4", version.ref = "antlr" } antlr-runtime = { group = "org.antlr", name = "antlr4-runtime", version.ref = "antlr" } +antlr-kotlin-runtime = { group = "com.strumenta", name = "antlr-kotlin-runtime", version.ref = "antlrKotlin" } jupiter-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junitJupiter" } jupiter-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junitJupiter" } @@ -86,8 +88,8 @@ slf4j-simple = { group = "org.slf4j", name = "slf4j-simple", version.ref = "slf4 kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } nebula-release = { id = "nebula.release", version.ref = "nebulaRelease" } gradle-nexus-publish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "gradleNexusPublish" } -kotest-multiplatform = { id = "io.kotest.multiplatform", version.ref = "kotest"} - +kotest-multiplatform = { id = "io.kotest.multiplatform", version.ref = "kotest" } +antlr-kotlin = { id = "com.strumenta.antlr-kotlin", version.ref = "antlrKotlin" } [bundles] jupiter = ["jupiter-api", "jupiter-engine"] diff --git a/orx-jvm/orx-expression-evaluator/.gitignore b/orx-expression-evaluator/.gitignore similarity index 100% rename from orx-jvm/orx-expression-evaluator/.gitignore rename to orx-expression-evaluator/.gitignore diff --git a/orx-jvm/orx-expression-evaluator/README.md b/orx-expression-evaluator/README.md similarity index 100% rename from orx-jvm/orx-expression-evaluator/README.md rename to orx-expression-evaluator/README.md diff --git a/orx-expression-evaluator/build.gradle.kts b/orx-expression-evaluator/build.gradle.kts new file mode 100644 index 00000000..8c28caef --- /dev/null +++ b/orx-expression-evaluator/build.gradle.kts @@ -0,0 +1,66 @@ +import com.strumenta.antlrkotlin.gradle.AntlrKotlinTask +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + org.openrndr.extra.convention.`kotlin-multiplatform` + alias(libs.plugins.antlr.kotlin) +} + +val generateKotlinGrammarSource = tasks.register("generateKotlinGrammarSource") { + dependsOn("cleanGenerateKotlinGrammarSource") + + // ANTLR .g4 files are under {example-project}/antlr + // Only include *.g4 files. This allows tools (e.g., IDE plugins) + // to generate temporary files inside the base path + source = fileTree(layout.projectDirectory.dir("src/commonMain/antlr")) { + include("**/*.g4") + } + + // We want the generated source files to have this package name + val pkgName = "org.openrndr.expressions.parser" + packageName = pkgName + + // We want visitors alongside listeners. + // The Kotlin target language is implicit, as is the file encoding (UTF-8) + arguments = listOf("-visitor") + + // Generated files are outputted inside build/generatedAntlr/{package-name} + val outDir = "generatedAntlr/${pkgName.replace(".", "/")}" + outputDirectory = layout.buildDirectory.dir(outDir).get().asFile +} + +tasks.withType { + kotlinOptions.freeCompilerArgs = listOf("-opt-in=kotlin.RequiresOptIn") +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(libs.antlr.kotlin.runtime) + implementation(libs.openrndr.application) + implementation(libs.openrndr.math) + implementation(libs.kotlin.coroutines) + implementation(project(":orx-property-watchers")) + implementation(project(":orx-noise")) + } + kotlin { + srcDir(layout.buildDirectory.dir("generatedAntlr")) + } + } + val jvmDemo by getting { + dependencies { + implementation(project(":orx-jvm:orx-gui")) + } + } + val jvmTest by getting { + dependencies { + implementation(libs.kluent) + } + } + } +} + +tasks.withType { + dependsOn(generateKotlinGrammarSource) +} diff --git a/orx-jvm/orx-expression-evaluator/src/main/antlr/KeyLangLexer.g4 b/orx-expression-evaluator/src/commonMain/antlr/KeyLangLexer.g4 similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/main/antlr/KeyLangLexer.g4 rename to orx-expression-evaluator/src/commonMain/antlr/KeyLangLexer.g4 diff --git a/orx-jvm/orx-expression-evaluator/src/main/antlr/KeyLangParser.g4 b/orx-expression-evaluator/src/commonMain/antlr/KeyLangParser.g4 similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/main/antlr/KeyLangParser.g4 rename to orx-expression-evaluator/src/commonMain/antlr/KeyLangParser.g4 diff --git a/orx-jvm/orx-expression-evaluator/src/main/kotlin/CompiledFunctions.kt b/orx-expression-evaluator/src/commonMain/kotlin/CompiledFunctions.kt similarity index 98% rename from orx-jvm/orx-expression-evaluator/src/main/kotlin/CompiledFunctions.kt rename to orx-expression-evaluator/src/commonMain/kotlin/CompiledFunctions.kt index fd482d18..4fa07ac0 100644 --- a/orx-jvm/orx-expression-evaluator/src/main/kotlin/CompiledFunctions.kt +++ b/orx-expression-evaluator/src/commonMain/kotlin/CompiledFunctions.kt @@ -1,6 +1,7 @@ package org.openrndr.extra.expressions -import org.antlr.v4.runtime.tree.ParseTreeWalker +import org.antlr.v4.kotlinruntime.tree.ParseTreeWalker + /** * Compile a (Double)->Double function from an expression string diff --git a/orx-jvm/orx-expression-evaluator/src/main/kotlin/ExpressionDelegate.kt b/orx-expression-evaluator/src/commonMain/kotlin/ExpressionDelegate.kt similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/main/kotlin/ExpressionDelegate.kt rename to orx-expression-evaluator/src/commonMain/kotlin/ExpressionDelegate.kt diff --git a/orx-jvm/orx-expression-evaluator/src/main/kotlin/Expressions.kt b/orx-expression-evaluator/src/commonMain/kotlin/Expressions.kt similarity index 93% rename from orx-jvm/orx-expression-evaluator/src/main/kotlin/Expressions.kt rename to orx-expression-evaluator/src/commonMain/kotlin/Expressions.kt index 61f60d74..7178cae7 100644 --- a/orx-jvm/orx-expression-evaluator/src/main/kotlin/Expressions.kt +++ b/orx-expression-evaluator/src/commonMain/kotlin/Expressions.kt @@ -1,11 +1,13 @@ package org.openrndr.extra.expressions -import KeyLangLexer -import KeyLangParser -import KeyLangParserBaseListener -import org.antlr.v4.runtime.* -import org.antlr.v4.runtime.tree.ParseTreeWalker -import org.antlr.v4.runtime.tree.TerminalNode + + +import org.antlr.v4.kotlinruntime.* +import org.antlr.v4.kotlinruntime.tree.ParseTreeWalker +import org.antlr.v4.kotlinruntime.tree.TerminalNode +import org.openrndr.expressions.parser.KeyLangLexer +import org.openrndr.expressions.parser.KeyLangParser +import org.openrndr.expressions.parser.KeyLangParserBaseListener import org.openrndr.extra.noise.uniform import org.openrndr.math.* @@ -84,11 +86,11 @@ internal class ExpressionListener( val right = doubleStack.pop() val left = doubleStack.pop() val result = when (val operator = ctx.operator?.type) { - KeyLangParser.PLUS -> left + right - KeyLangParser.MINUS -> left - right - KeyLangParser.ASTERISK -> left * right - KeyLangParser.DIVISION -> left / right - KeyLangParser.PERCENTAGE -> mod(left, right) + KeyLangLexer.Tokens.PLUS.id -> left + right + KeyLangParser.Tokens.MINUS.id -> left - right + KeyLangParser.Tokens.ASTERISK.id -> left * right + KeyLangParser.Tokens.DIVISION.id -> left / right + KeyLangParser.Tokens.PERCENTAGE.id -> mod(left, right) else -> error("operator '$operator' not implemented") } doubleStack.push(result) @@ -103,10 +105,10 @@ internal class ExpressionListener( val left = doubleStack.pop() val right = doubleStack.pop() val result = when (val operator = ctx.operator?.type) { - KeyLangParser.PLUS -> left + right - KeyLangParser.MINUS -> right - left - KeyLangParser.ASTERISK -> left * right - KeyLangParser.DIVISION -> left / right + KeyLangParser.Tokens.PLUS.id -> left + right + KeyLangParser.Tokens.MINUS.id -> right - left + KeyLangParser.Tokens.ASTERISK.id -> left * right + KeyLangParser.Tokens.DIVISION.id -> left / right else -> error("operator '$operator' not implemented") } doubleStack.push(result) @@ -245,13 +247,13 @@ internal class ExpressionListener( override fun visitTerminal(node: TerminalNode) { val type = node.symbol?.type - if (type == KeyLangParser.INTLIT) { + if (type == KeyLangParser.Tokens.INTLIT.id) { doubleStack.push(node.text.toDouble()) } - if (type == KeyLangParser.DECLIT) { + if (type == KeyLangParser.Tokens.DECLIT.id) { doubleStack.push(node.text.toDouble()) } - if (type == KeyLangParser.ID) { + if (type == KeyLangParser.Tokens.ID.id) { val name = node.text.replace("`", "") @Suppress("DIVISION_BY_ZERO") when (val idType = idTypeStack.pop()) { @@ -409,11 +411,11 @@ fun evaluateExpression( parser.removeErrorListeners() parser.addErrorListener(object : BaseErrorListener() { override fun syntaxError( - recognizer: Recognizer<*, *>?, + recognizer: Recognizer<*, *>, offendingSymbol: Any?, line: Int, charPositionInLine: Int, - msg: String?, + msg: String, e: RecognitionException? ) { throw ExpressionException("parser error in expression: '$expression'; [line: $line, character: $charPositionInLine ${offendingSymbol?.let { ", near: $it" } ?: ""} ]") @@ -440,11 +442,11 @@ fun compileExpression( parser.removeErrorListeners() parser.addErrorListener(object : BaseErrorListener() { override fun syntaxError( - recognizer: Recognizer<*, *>?, + recognizer: Recognizer<*, *>, offendingSymbol: Any?, line: Int, charPositionInLine: Int, - msg: String?, + msg: String, e: RecognitionException? ) { throw ExpressionException("parser error in expression: '$expression'; [line: $line, character: $charPositionInLine ${offendingSymbol?.let { ", near: $it" } ?: ""} ]") @@ -470,11 +472,11 @@ internal fun expressionRoot(expression: String): KeyLangParser.KeyLangFileContex parser.removeErrorListeners() parser.addErrorListener(object : BaseErrorListener() { override fun syntaxError( - recognizer: Recognizer<*, *>?, + recognizer: Recognizer<*, *>, offendingSymbol: Any?, line: Int, charPositionInLine: Int, - msg: String?, + msg: String, e: RecognitionException? ) { throw ExpressionException("parser error in expression: '$expression'; [line: $line, character: $charPositionInLine ${offendingSymbol?.let { ", near: $it" } ?: ""} ]") diff --git a/orx-jvm/orx-expression-evaluator/src/demo/kotlin/DemoExpressionEvaluator01.kt b/orx-expression-evaluator/src/jvmDemo/kotlin/DemoExpressionEvaluator01.kt similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/demo/kotlin/DemoExpressionEvaluator01.kt rename to orx-expression-evaluator/src/jvmDemo/kotlin/DemoExpressionEvaluator01.kt diff --git a/orx-jvm/orx-expression-evaluator/src/demo/kotlin/DemoExpressionEvaluator02.kt b/orx-expression-evaluator/src/jvmDemo/kotlin/DemoExpressionEvaluator02.kt similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/demo/kotlin/DemoExpressionEvaluator02.kt rename to orx-expression-evaluator/src/jvmDemo/kotlin/DemoExpressionEvaluator02.kt diff --git a/orx-jvm/orx-expression-evaluator/src/test/kotlin/TestCompiledExpression.kt b/orx-expression-evaluator/src/jvmTest/kotlin/TestCompiledExpression.kt similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/test/kotlin/TestCompiledExpression.kt rename to orx-expression-evaluator/src/jvmTest/kotlin/TestCompiledExpression.kt diff --git a/orx-jvm/orx-expression-evaluator/src/test/kotlin/TestCompiledFunctions.kt b/orx-expression-evaluator/src/jvmTest/kotlin/TestCompiledFunctions.kt similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/test/kotlin/TestCompiledFunctions.kt rename to orx-expression-evaluator/src/jvmTest/kotlin/TestCompiledFunctions.kt diff --git a/orx-jvm/orx-expression-evaluator/src/test/kotlin/TestExpressionDelegates.kt b/orx-expression-evaluator/src/jvmTest/kotlin/TestExpressionDelegates.kt similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/test/kotlin/TestExpressionDelegates.kt rename to orx-expression-evaluator/src/jvmTest/kotlin/TestExpressionDelegates.kt diff --git a/orx-jvm/orx-expression-evaluator/src/test/kotlin/TestExpressionErrors.kt b/orx-expression-evaluator/src/jvmTest/kotlin/TestExpressionErrors.kt similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/test/kotlin/TestExpressionErrors.kt rename to orx-expression-evaluator/src/jvmTest/kotlin/TestExpressionErrors.kt diff --git a/orx-jvm/orx-expression-evaluator/src/test/kotlin/TestExpressions.kt b/orx-expression-evaluator/src/jvmTest/kotlin/TestExpressions.kt similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/test/kotlin/TestExpressions.kt rename to orx-expression-evaluator/src/jvmTest/kotlin/TestExpressions.kt diff --git a/orx-jvm/orx-expression-evaluator/src/test/kotlin/TestOperators.kt b/orx-expression-evaluator/src/jvmTest/kotlin/TestOperators.kt similarity index 100% rename from orx-jvm/orx-expression-evaluator/src/test/kotlin/TestOperators.kt rename to orx-expression-evaluator/src/jvmTest/kotlin/TestOperators.kt diff --git a/orx-jvm/orx-expression-evaluator/build.gradle.kts b/orx-jvm/orx-expression-evaluator/build.gradle.kts deleted file mode 100644 index cc6efafa..00000000 --- a/orx-jvm/orx-expression-evaluator/build.gradle.kts +++ /dev/null @@ -1,33 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - -plugins { - org.openrndr.extra.convention.`kotlin-jvm` - antlr -} - -tasks.generateGrammarSource { - maxHeapSize = "64m" - arguments.addAll(listOf("-visitor", "-long-messages")) -} - - -tasks.withType { - kotlinOptions.freeCompilerArgs = listOf("-opt-in=kotlin.RequiresOptIn") -} - -dependencies { - antlr(libs.antlr.core) - implementation(libs.antlr.runtime) - implementation(libs.openrndr.application) - implementation(libs.openrndr.math) - implementation(libs.kotlin.coroutines) - implementation(project(":orx-property-watchers")) - implementation(project(":orx-noise")) - testImplementation(libs.kluent) - demoImplementation(project(":orx-jvm:orx-gui")) -} - -tasks.getByName("compileKotlin").dependsOn("generateGrammarSource") -tasks.getByName("compileDemoKotlin").dependsOn("generateDemoGrammarSource") -tasks.getByName("compileTestKotlin").dependsOn("generateTestGrammarSource") -tasks.getByName("sourcesJar").dependsOn("generateGrammarSource") diff --git a/orx-jvm/orx-keyframer/build.gradle.kts b/orx-jvm/orx-keyframer/build.gradle.kts index 8733e6e6..3d2d569a 100644 --- a/orx-jvm/orx-keyframer/build.gradle.kts +++ b/orx-jvm/orx-keyframer/build.gradle.kts @@ -15,7 +15,7 @@ dependencies { implementation(libs.kotlin.reflect) implementation(project(":orx-noise")) implementation(project(":orx-easing")) - api(project(":orx-jvm:orx-expression-evaluator")) + api(project(":orx-expression-evaluator")) demoImplementation(project(":orx-jvm:orx-panel")) testImplementation(libs.kluent) } diff --git a/orx-jvm/orx-panel/build.gradle.kts b/orx-jvm/orx-panel/build.gradle.kts index 145f0cf5..c77a904d 100644 --- a/orx-jvm/orx-panel/build.gradle.kts +++ b/orx-jvm/orx-panel/build.gradle.kts @@ -14,7 +14,7 @@ tasks.test { } dependencies { - implementation(project(":orx-jvm:orx-expression-evaluator")) + implementation(project(":orx-expression-evaluator")) implementation(libs.openrndr.application) implementation(libs.openrndr.math) implementation(libs.kotlin.coroutines) diff --git a/settings.gradle.kts b/settings.gradle.kts index c387c17d..f569c8d9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -27,7 +27,7 @@ include( "orx-jvm:orx-dnk3", "orx-easing", "orx-envelopes", - "orx-jvm:orx-expression-evaluator", + "orx-expression-evaluator", "orx-jvm:orx-file-watcher", "orx-parameters", "orx-fx",