From be8cf96f005df712b0bd3f6eeafb3baeabab89fd Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sun, 3 May 2026 20:37:32 +0700 Subject: [PATCH 01/15] Switch line ending policy to CRLF Set `* -text` so git stops normalising EOLs entirely; the working tree keeps whatever the editor wrote, which is CRLF in this project, and the stored blobs match. Pair with `end_of_line = crlf` in .editorconfig so editor-side defaults agree. Co-Authored-By: Claude Opus 4.7 (1M context) --- .editorconfig | 2 +- .gitattributes | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.editorconfig b/.editorconfig index aa0df99..c088a82 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,7 +2,7 @@ root = true [*] charset = utf-8 -end_of_line = lf +end_of_line = crlf insert_final_newline = false indent_size = 4 indent_style = space diff --git a/.gitattributes b/.gitattributes index 94f480d..5378fe0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -* text=auto eol=lf \ No newline at end of file +* -text \ No newline at end of file From 81910b22c2366630f16b1bdab589b9ca82240f03 Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Mon, 4 May 2026 04:25:15 +0700 Subject: [PATCH 02/15] Split monorepo into per-region Gradle modules Break the single project into lexer/parser/runtime/runtime-compiler subprojects (root keeps the JMH benchmark and aggregator publish). Distribute MochaEngine's regions: parsing stays on MolangParser, interpreter+bindings move to a new MolangInterpreter in runtime, compiler stays on MolangCompiler with its own parse-error handler. MochaEngine becomes a thin holder exposing interpreter()/compiler(). prepareEval now returns Supplier so the interpreter does not have to depend on the compiler module. Co-Authored-By: Claude Opus 4.7 (1M context) --- build.gradle | 105 ++-- lexer/build.gradle | 1 + .../team/unnamed/mocha/lexer/Characters.java | 0 .../java/team/unnamed/mocha/lexer/Cursor.java | 0 .../team/unnamed/mocha/lexer/MolangLexer.java | 0 .../unnamed/mocha/lexer/MolangLexerImpl.java | 0 .../java/team/unnamed/mocha/lexer/Token.java | 0 .../team/unnamed/mocha/lexer/TokenKind.java | 0 .../unnamed/mocha/lexer/package-info.java | 0 .../team/unnamed/mocha/lexer/LexerTest.java | 0 parser/build.gradle | 4 + .../unnamed/mocha/parser/MolangParser.java | 0 .../mocha/parser/MolangParserImpl.java | 0 .../unnamed/mocha/parser/ParseException.java | 0 .../mocha/parser/ast/AccessExpression.java | 0 .../parser/ast/ArrayAccessExpression.java | 0 .../mocha/parser/ast/BinaryExpression.java | 0 .../mocha/parser/ast/CallExpression.java | 0 .../parser/ast/ExecutionScopeExpression.java | 0 .../unnamed/mocha/parser/ast/Expression.java | 0 .../mocha/parser/ast/ExpressionVisitor.java | 0 .../mocha/parser/ast/FloatExpression.java | 0 .../parser/ast/IdentifierExpression.java | 0 .../mocha/parser/ast/StatementExpression.java | 0 .../mocha/parser/ast/StringExpression.java | 0 .../ast/TernaryConditionalExpression.java | 0 .../mocha/parser/ast/UnaryExpression.java | 0 .../mocha/parser/ast/package-info.java | 0 .../unnamed/mocha/parser/package-info.java | 0 .../unnamed/mocha/util/ExprBytesUtils.java | 0 .../mocha/util/ExpressionListUtils.java | 0 .../mocha/util/network/ProtocolUtils.java | 0 .../mocha/util/network/VarIntUtils.java | 0 .../mocha/parser/ArrayAccessParseTest.java | 4 +- .../unnamed/mocha/parser/CallParseTest.java | 4 +- .../unnamed/mocha/parser/DoubleParseTest.java | 2 +- .../unnamed/mocha/parser/HierarchyTest.java | 54 +-- .../mocha/parser/ParserAssertions.java | 229 +++++---- .../team/unnamed/mocha/parser/StringTest.java | 5 +- .../mocha/parser/TernaryParseTest.java | 2 +- runtime-compiler/build.gradle | 24 + .../java/team/unnamed/mocha/MochaEngine.java | 103 ++++ .../mocha/runtime/CompileVisitResult.java | 0 .../mocha/runtime/FunctionCompileState.java | 0 .../unnamed/mocha/runtime/MochaFunction.java | 0 .../unnamed/mocha/runtime/MolangCompiler.java | 101 +++- .../mocha/runtime/MolangCompilingVisitor.java | 0 .../compiled/MochaCompiledFunction.java | 0 .../unnamed/mocha/runtime/compiled/Named.java | 0 .../unnamed/mocha/util/ClassFileUtil.java | 0 .../team/unnamed/mocha/MochaAssertions.java | 56 +++ .../mocha/runtime/ArrayAccessRuntimeTest.java | 2 +- .../mocha/runtime/BreakContinueTest.java | 4 +- .../mocha/runtime/BytecodeKotlinTest.kt | 20 +- .../mocha/runtime/CaseSensitivityTest.java | 0 .../unnamed/mocha/runtime/CompareTest.java | 4 +- .../mocha/runtime/ConstantValuesTest.java | 2 +- .../unnamed/mocha/runtime/FibonacciTest.java | 2 +- .../unnamed/mocha/runtime/ForEachTest.java | 4 +- .../mocha/runtime/IndividualScopeTest.java | 6 +- .../runtime/InstanceMethodBindingTest.java | 6 +- .../runtime/IntCompiledFunctionTest.java | 2 +- .../unnamed/mocha/runtime/ParseErrorTest.java | 6 +- .../runtime/arrow/ArrowOperatorTest.java | 6 +- .../unnamed/mocha/runtime/arrow/Player.java | 0 .../unnamed/mocha/runtime/arrow/World.java | 0 .../jvm/ArithmeticCompiledRuntimeTest.java | 14 +- .../jvm/LogicalCompiledRuntimeTest.java | 4 +- .../runtime/jvm/MathCompiledRuntimeTest.java | 4 +- .../mocha/runtime/jvm/MolangCompilerTest.java | 10 +- .../mocha/runtime/standart/MochaMathTest.java | 2 +- .../src}/test/resources/expectations.txt | 0 .../src}/test/resources/tests.txt | 0 runtime/build.gradle | 3 + .../mocha/runtime/ExecutionContext.java | 0 .../mocha/runtime/ExpressionInliner.java | 0 .../mocha/runtime/ExpressionInterpreter.java | 0 .../mocha/runtime/IsConstantExpression.java | 0 .../team/unnamed/mocha/runtime/JavaTypes.java | 0 .../mocha/runtime/MolangInterpreter.java | 394 +++++++++++++++ .../team/unnamed/mocha/runtime/Scope.java | 0 .../team/unnamed/mocha/runtime/ScopeImpl.java | 0 .../mocha/runtime/TypeCastException.java | 0 .../runtime/binding/BindExternalFunction.java | 0 .../mocha/runtime/binding/Binding.java | 0 .../unnamed/mocha/runtime/binding/Entity.java | 0 .../runtime/binding/JavaFieldBinding.java | 0 .../mocha/runtime/binding/JavaFunction.java | 0 .../runtime/binding/JavaObjectBinding.java | 0 .../unnamed/mocha/runtime/binding/Lazy.java | 0 .../runtime/binding/ReflectiveFunction.java | 0 .../runtime/binding/RegisteredBinding.java | 0 .../mocha/runtime/standard/MochaMath.java | 0 .../mocha/runtime/value/ArrayValue.java | 0 .../unnamed/mocha/runtime/value/Function.java | 0 .../mocha/runtime/value/JavaValue.java | 0 .../runtime/value/MutableObjectBinding.java | 0 .../mocha/runtime/value/NumberValue.java | 0 .../mocha/runtime/value/ObjectProperty.java | 0 .../runtime/value/ObjectPropertyImpl.java | 0 .../mocha/runtime/value/ObjectValue.java | 0 .../mocha/runtime/value/StringValue.java | 0 .../unnamed/mocha/runtime/value/Value.java | 0 .../util/CaseInsensitiveStringHashMap.java | 0 .../mocha/runtime/value/ValueOfTest.java | 0 .../CaseInsensitiveStringHashMapTest.java | 0 scripts/generate_expectations.js | 2 +- settings.gradle.kts | 7 + .../team/unnamed/mocha/CompareBenchmark.java | 2 +- .../java/team/unnamed/mocha/MochaEngine.java | 458 ------------------ .../team/unnamed/mocha/MochaEngineImpl.java | 243 ---------- 111 files changed, 962 insertions(+), 939 deletions(-) create mode 100644 lexer/build.gradle rename {src => lexer/src}/main/java/team/unnamed/mocha/lexer/Characters.java (100%) rename {src => lexer/src}/main/java/team/unnamed/mocha/lexer/Cursor.java (100%) rename {src => lexer/src}/main/java/team/unnamed/mocha/lexer/MolangLexer.java (100%) rename {src => lexer/src}/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java (100%) rename {src => lexer/src}/main/java/team/unnamed/mocha/lexer/Token.java (100%) rename {src => lexer/src}/main/java/team/unnamed/mocha/lexer/TokenKind.java (100%) rename {src => lexer/src}/main/java/team/unnamed/mocha/lexer/package-info.java (100%) rename {src => lexer/src}/test/java/team/unnamed/mocha/lexer/LexerTest.java (100%) create mode 100644 parser/build.gradle rename {src => parser/src}/main/java/team/unnamed/mocha/parser/MolangParser.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/MolangParserImpl.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ParseException.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/BinaryExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/CallExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/Expression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/FloatExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/StringExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/ast/package-info.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/parser/package-info.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/util/ExprBytesUtils.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/util/ExpressionListUtils.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/util/network/ProtocolUtils.java (100%) rename {src => parser/src}/main/java/team/unnamed/mocha/util/network/VarIntUtils.java (100%) rename {src => parser/src}/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java (95%) rename {src => parser/src}/test/java/team/unnamed/mocha/parser/CallParseTest.java (95%) rename {src => parser/src}/test/java/team/unnamed/mocha/parser/DoubleParseTest.java (96%) rename {src => parser/src}/test/java/team/unnamed/mocha/parser/HierarchyTest.java (95%) rename src/test/java/team/unnamed/mocha/MochaAssertions.java => parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java (64%) rename {src => parser/src}/test/java/team/unnamed/mocha/parser/StringTest.java (91%) rename {src => parser/src}/test/java/team/unnamed/mocha/parser/TernaryParseTest.java (96%) create mode 100644 runtime-compiler/build.gradle create mode 100644 runtime-compiler/src/main/java/team/unnamed/mocha/MochaEngine.java rename {src => runtime-compiler/src}/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java (100%) rename {src => runtime-compiler/src}/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java (100%) rename {src => runtime-compiler/src}/main/java/team/unnamed/mocha/runtime/MochaFunction.java (100%) rename {src => runtime-compiler/src}/main/java/team/unnamed/mocha/runtime/MolangCompiler.java (76%) rename {src => runtime-compiler/src}/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java (100%) rename {src => runtime-compiler/src}/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java (100%) rename {src => runtime-compiler/src}/main/java/team/unnamed/mocha/runtime/compiled/Named.java (100%) rename {src => runtime-compiler/src}/main/java/team/unnamed/mocha/util/ClassFileUtil.java (100%) create mode 100644 runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/ArrayAccessRuntimeTest.java (97%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java (90%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/BytecodeKotlinTest.kt (63%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/CaseSensitivityTest.java (100%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/CompareTest.java (94%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java (91%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/FibonacciTest.java (97%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/ForEachTest.java (93%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/IndividualScopeTest.java (89%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java (86%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/IntCompiledFunctionTest.java (96%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java (85%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java (93%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/arrow/Player.java (100%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/arrow/World.java (100%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java (87%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java (92%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java (90%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/jvm/MolangCompilerTest.java (83%) rename {src => runtime-compiler/src}/test/java/team/unnamed/mocha/runtime/standart/MochaMathTest.java (94%) rename {src => runtime-compiler/src}/test/resources/expectations.txt (100%) rename {src => runtime-compiler/src}/test/resources/tests.txt (100%) create mode 100644 runtime/build.gradle rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/ExecutionContext.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/JavaTypes.java (100%) create mode 100644 runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/Scope.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/ScopeImpl.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/TypeCastException.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/binding/Binding.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/binding/Entity.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/binding/Lazy.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/standard/MochaMath.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/value/Function.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/value/JavaValue.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/value/NumberValue.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/value/StringValue.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/runtime/value/Value.java (100%) rename {src => runtime/src}/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java (100%) rename {src => runtime/src}/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java (100%) rename {src => runtime/src}/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java (100%) delete mode 100644 src/main/java/team/unnamed/mocha/MochaEngine.java delete mode 100644 src/main/java/team/unnamed/mocha/MochaEngineImpl.java diff --git a/build.gradle b/build.gradle index 2c54b1e..ef349f9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,45 +1,99 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "2.3.21" + id "org.jetbrains.kotlin.jvm" version "2.3.21" apply false id "java-library" id "maven-publish" id("net.neoforged.licenser") version "0.7.5" id("me.champeau.jmh") version "0.7.3" } -repositories { - mavenCentral() - maven { - url = uri("https://repo.redlance.org/public") // mirroring https://maven.pkg.github.com/bedrockk/MoLang +allprojects { + group = rootProject.group + version = rootProject.version + + repositories { + mavenCentral() + maven { + url = uri("https://repo.redlance.org/public") // mirroring https://maven.pkg.github.com/bedrockk/MoLang + } + maven { url = "https://maven.blamejared.com/" } // moonflower's molang-compiler } - maven { url = "https://maven.blamejared.com/"} // moonflower's molang-compiler } -dependencies { - implementation api("io.netty:netty-buffer:4.2.12.Final") - compileOnlyApi("org.jetbrains:annotations:26.1.0") +subprojects { + apply plugin: "java-library" + apply plugin: "maven-publish" + apply plugin: "net.neoforged.licenser" - // tests - testImplementation("org.junit.jupiter:junit-jupiter-api:6.0.3") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:6.0.3") - testRuntimeOnly("org.junit.platform:junit-platform-launcher:6.0.3") - testImplementation("org.jetbrains.kotlin:kotlin-stdlib:2.3.21") + dependencies { + compileOnlyApi("org.jetbrains:annotations:26.1.0") + + testImplementation("org.junit.jupiter:junit-jupiter-api:6.0.3") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:6.0.3") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:6.0.3") + } + + tasks.named("test") { + useJUnitPlatform() + } + + tasks.named("compileJava") { + sourceCompatibility = "24" + targetCompatibility = "24" + } + + tasks.named("javadoc") { + failOnError = false + } + + java { + withJavadocJar() + withSourcesJar() + } + + jar { + manifest.attributes("FMLModType": "GAMELIBRARY") + } + + license { + header.set(rootProject.resources.text.fromFile("header.txt")) + include("**/*.java") + newLine = false + } + + publishing { + repositories { + maven { + name = "RedlanceMinecraft" + url = "https://repo.redlance.org/public" + credentials { + username = "dima_dencep" + password = System.getenv("MAVEN_PASSWORD") + } + } + } + publications { + maven(MavenPublication) { + groupId = "com.zigythebird" + artifactId = "mochafloats-${project.name}" + version = project.version + from components.java + } + } + } +} + +dependencies { + api project(":lexer") + api project(":parser") + api project(":runtime") + api project(":runtime-compiler") // performance comparison with other libraries jmhImplementation("com.bedrockk:molang:1.0-SNAPSHOT") jmhImplementation("gg.moonflower:molang-compiler:3.1.1.19") } -tasks.register('generateExpectations', Exec) { - def nvmDir = file("${System.getenv('HOME')}/.nvm/versions/node") - executable nvmDir.isDirectory() ? "${nvmDir.listFiles().sort().last()}/bin/node" : 'node' - args 'scripts/generate_expectations.js' -} - tasks { - test { - useJUnitPlatform() - dependsOn tasks.generateExpectations - } compileJmhJava { sourceCompatibility = "24" targetCompatibility = "24" @@ -51,9 +105,6 @@ tasks { javadoc { failOnError = false } - compileKotlin { - enabled = false - } } license { diff --git a/lexer/build.gradle b/lexer/build.gradle new file mode 100644 index 0000000..2fbc1d4 --- /dev/null +++ b/lexer/build.gradle @@ -0,0 +1 @@ +// no internal dependencies diff --git a/src/main/java/team/unnamed/mocha/lexer/Characters.java b/lexer/src/main/java/team/unnamed/mocha/lexer/Characters.java similarity index 100% rename from src/main/java/team/unnamed/mocha/lexer/Characters.java rename to lexer/src/main/java/team/unnamed/mocha/lexer/Characters.java diff --git a/src/main/java/team/unnamed/mocha/lexer/Cursor.java b/lexer/src/main/java/team/unnamed/mocha/lexer/Cursor.java similarity index 100% rename from src/main/java/team/unnamed/mocha/lexer/Cursor.java rename to lexer/src/main/java/team/unnamed/mocha/lexer/Cursor.java diff --git a/src/main/java/team/unnamed/mocha/lexer/MolangLexer.java b/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexer.java similarity index 100% rename from src/main/java/team/unnamed/mocha/lexer/MolangLexer.java rename to lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexer.java diff --git a/src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java b/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java similarity index 100% rename from src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java rename to lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java diff --git a/src/main/java/team/unnamed/mocha/lexer/Token.java b/lexer/src/main/java/team/unnamed/mocha/lexer/Token.java similarity index 100% rename from src/main/java/team/unnamed/mocha/lexer/Token.java rename to lexer/src/main/java/team/unnamed/mocha/lexer/Token.java diff --git a/src/main/java/team/unnamed/mocha/lexer/TokenKind.java b/lexer/src/main/java/team/unnamed/mocha/lexer/TokenKind.java similarity index 100% rename from src/main/java/team/unnamed/mocha/lexer/TokenKind.java rename to lexer/src/main/java/team/unnamed/mocha/lexer/TokenKind.java diff --git a/src/main/java/team/unnamed/mocha/lexer/package-info.java b/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java similarity index 100% rename from src/main/java/team/unnamed/mocha/lexer/package-info.java rename to lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java diff --git a/src/test/java/team/unnamed/mocha/lexer/LexerTest.java b/lexer/src/test/java/team/unnamed/mocha/lexer/LexerTest.java similarity index 100% rename from src/test/java/team/unnamed/mocha/lexer/LexerTest.java rename to lexer/src/test/java/team/unnamed/mocha/lexer/LexerTest.java diff --git a/parser/build.gradle b/parser/build.gradle new file mode 100644 index 0000000..703ec02 --- /dev/null +++ b/parser/build.gradle @@ -0,0 +1,4 @@ +dependencies { + api project(":lexer") + api "io.netty:netty-buffer:4.2.12.Final" +} diff --git a/src/main/java/team/unnamed/mocha/parser/MolangParser.java b/parser/src/main/java/team/unnamed/mocha/parser/MolangParser.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/MolangParser.java rename to parser/src/main/java/team/unnamed/mocha/parser/MolangParser.java diff --git a/src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java b/parser/src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java rename to parser/src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java diff --git a/src/main/java/team/unnamed/mocha/parser/ParseException.java b/parser/src/main/java/team/unnamed/mocha/parser/ParseException.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ParseException.java rename to parser/src/main/java/team/unnamed/mocha/parser/ParseException.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/BinaryExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/BinaryExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/BinaryExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/BinaryExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/Expression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/Expression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/Expression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/Expression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/FloatExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/FloatExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/FloatExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/FloatExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java diff --git a/src/main/java/team/unnamed/mocha/parser/ast/package-info.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/ast/package-info.java rename to parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java diff --git a/src/main/java/team/unnamed/mocha/parser/package-info.java b/parser/src/main/java/team/unnamed/mocha/parser/package-info.java similarity index 100% rename from src/main/java/team/unnamed/mocha/parser/package-info.java rename to parser/src/main/java/team/unnamed/mocha/parser/package-info.java diff --git a/src/main/java/team/unnamed/mocha/util/ExprBytesUtils.java b/parser/src/main/java/team/unnamed/mocha/util/ExprBytesUtils.java similarity index 100% rename from src/main/java/team/unnamed/mocha/util/ExprBytesUtils.java rename to parser/src/main/java/team/unnamed/mocha/util/ExprBytesUtils.java diff --git a/src/main/java/team/unnamed/mocha/util/ExpressionListUtils.java b/parser/src/main/java/team/unnamed/mocha/util/ExpressionListUtils.java similarity index 100% rename from src/main/java/team/unnamed/mocha/util/ExpressionListUtils.java rename to parser/src/main/java/team/unnamed/mocha/util/ExpressionListUtils.java diff --git a/src/main/java/team/unnamed/mocha/util/network/ProtocolUtils.java b/parser/src/main/java/team/unnamed/mocha/util/network/ProtocolUtils.java similarity index 100% rename from src/main/java/team/unnamed/mocha/util/network/ProtocolUtils.java rename to parser/src/main/java/team/unnamed/mocha/util/network/ProtocolUtils.java diff --git a/src/main/java/team/unnamed/mocha/util/network/VarIntUtils.java b/parser/src/main/java/team/unnamed/mocha/util/network/VarIntUtils.java similarity index 100% rename from src/main/java/team/unnamed/mocha/util/network/VarIntUtils.java rename to parser/src/main/java/team/unnamed/mocha/util/network/VarIntUtils.java diff --git a/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java b/parser/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java similarity index 95% rename from src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java rename to parser/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java index 164ac8d..97b4b03 100644 --- a/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java @@ -28,8 +28,8 @@ import java.util.Collections; -import static team.unnamed.mocha.MochaAssertions.assertCreateTree; -import static team.unnamed.mocha.MochaAssertions.assertParseError; +import static team.unnamed.mocha.parser.ParserAssertions.assertCreateTree; +import static team.unnamed.mocha.parser.ParserAssertions.assertParseError; class ArrayAccessParseTest { @Test diff --git a/src/test/java/team/unnamed/mocha/parser/CallParseTest.java b/parser/src/test/java/team/unnamed/mocha/parser/CallParseTest.java similarity index 95% rename from src/test/java/team/unnamed/mocha/parser/CallParseTest.java rename to parser/src/test/java/team/unnamed/mocha/parser/CallParseTest.java index cf5ac4e..69c9fa7 100644 --- a/src/test/java/team/unnamed/mocha/parser/CallParseTest.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/CallParseTest.java @@ -29,8 +29,8 @@ import java.util.Arrays; import java.util.Collections; -import static team.unnamed.mocha.MochaAssertions.assertCreateTree; -import static team.unnamed.mocha.MochaAssertions.assertParseError; +import static team.unnamed.mocha.parser.ParserAssertions.assertCreateTree; +import static team.unnamed.mocha.parser.ParserAssertions.assertParseError; class CallParseTest { @Test diff --git a/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java b/parser/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java similarity index 96% rename from src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java rename to parser/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java index 14effc1..9e24116 100644 --- a/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java @@ -28,7 +28,7 @@ import team.unnamed.mocha.parser.ast.IdentifierExpression; import team.unnamed.mocha.parser.ast.UnaryExpression; -import static team.unnamed.mocha.MochaAssertions.assertCreateTree; +import static team.unnamed.mocha.parser.ParserAssertions.assertCreateTree; class DoubleParseTest { @Test diff --git a/src/test/java/team/unnamed/mocha/parser/HierarchyTest.java b/parser/src/test/java/team/unnamed/mocha/parser/HierarchyTest.java similarity index 95% rename from src/test/java/team/unnamed/mocha/parser/HierarchyTest.java rename to parser/src/test/java/team/unnamed/mocha/parser/HierarchyTest.java index 45b8562..bab591d 100644 --- a/src/test/java/team/unnamed/mocha/parser/HierarchyTest.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/HierarchyTest.java @@ -1,30 +1,29 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; import team.unnamed.mocha.parser.ast.BinaryExpression; import team.unnamed.mocha.parser.ast.Expression; @@ -32,12 +31,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static team.unnamed.mocha.MochaAssertions.assertCreateSameTree; +import static team.unnamed.mocha.parser.ParserAssertions.assertCreateSameTree; +import static team.unnamed.mocha.parser.ParserAssertions.parse; class HierarchyTest { @Test void test_logical_hierarchy() throws Exception { - List expressions = MochaEngine.createStandard().parse("age <= 5 || age >= 70"); + List expressions = parse("age <= 5 || age >= 70"); assertEquals(1, expressions.size(), "Size must be 1: " + expressions); expressions.forEach(System.out::println); diff --git a/src/test/java/team/unnamed/mocha/MochaAssertions.java b/parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java similarity index 64% rename from src/test/java/team/unnamed/mocha/MochaAssertions.java rename to parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java index b51715a..574fa8c 100644 --- a/src/test/java/team/unnamed/mocha/MochaAssertions.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java @@ -1,121 +1,108 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.parser.ParseException; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.util.ExprBytesUtils; - -import java.util.Arrays; -import java.util.List; -import java.util.function.UnaryOperator; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - -public final class MochaAssertions { - private MochaAssertions() { - throw new UnsupportedOperationException("This class cannot be instantiated"); - } - - public static void assertCreateSameTree(final @NotNull String expr1, final @NotNull String expr2) throws Exception { - final MochaEngine engine = MochaEngine.createStandard(); - final List expressions1 = engine.parse(expr1); - final List expressions2 = engine.parse(expr2); - assertEquals(expressions1, expressions2, () -> "Expressions:\n\t- " + - expr1 + - "\n\t- " + - expr2 + - "\nGenerated different syntax trees:\n\t- " + - expressions1 + - "\n\t- " + - expressions2); - } - - public static void assertCreateTree(final @NotNull String expr, final @NotNull Expression @NotNull ... expressions) { - assertCreateTree(expr, Arrays.asList(expressions)); - } - - public static void assertCreateTree(final @NotNull String expr, final List expressions) { - final MochaEngine engine = MochaEngine.createStandard(); - final List parsed; - try { - parsed = engine.parse(expr); - } catch (final ParseException e) { - fail("Failed to parse expression: '" + expr + "'", e); - return; - } - - { // Network testing - ByteBuf buf = Unpooled.buffer(); - ExprBytesUtils.writeExpressions(expressions, buf); - - List readed = ExprBytesUtils.readExpressions(buf); - buf.release(); - - assertEquals(readed, expressions); - } - - assertEquals( - expressions, - parsed, - () -> "Expression: '" + expr + "' generated unexpected syntax tree:\n\t" + - "- Expected: " + expressions + "\n\t" + - "- Got: " + parsed - ); - } - - public static void assertParseError(final @NotNull String expr, final int column) { - final MochaEngine engine = MochaEngine.createStandard(); - try { - final List expressions = engine.parse(expr); - fail("Expected parse error at column " + column + " for expression: '" + expr + "', instead, it was parsed as: " + expressions); - } catch (final ParseException e) { - assertEquals(column, e.cursor().column(), "Expected parse error at column " + column + " for expression: '" + expr + "'"); - } - } - - public static void assertEvaluates(final double expected, final @NotNull String expr, final @NotNull UnaryOperator> configurer) { - MochaEngine engine = MochaEngine.createStandard(); - engine = configurer.apply(engine); - final double result = engine.eval(expr); - assertEquals(expected, result, 0.0001, () -> "Expression: '" + expr + "' evaluated to " + result + ", expected " + expected); - } - - public static void assertEvaluates(final double expected, final @NotNull String expr) { - assertEvaluates(expected, expr, engine -> engine); - } - - public static void assertEvaluatesAndCompiles(final double expected, final @NotNull String expr) { - final MochaEngine engine = MochaEngine.createStandard(); - final double result = engine.eval(expr); - assertEquals(expected, result, 0.0001, () -> "(Interpreted) expression: '" + expr + "' evaluated to " + result + ", expected " + expected); - - final double compiledResult = engine.compile(expr).evaluate(); - assertEquals(expected, compiledResult, 0.0001, () -> "(Compiled) expression: '" + expr + "' evaluated to " + compiledResult + ", expected " + expected); - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.jetbrains.annotations.NotNull; +import team.unnamed.mocha.parser.ast.Expression; +import team.unnamed.mocha.util.ExprBytesUtils; + +import java.io.IOException; +import java.io.StringReader; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +public final class ParserAssertions { + private ParserAssertions() { + throw new UnsupportedOperationException("This class cannot be instantiated"); + } + + public static @NotNull List parse(final @NotNull String expr) throws ParseException { + try (final StringReader reader = new StringReader(expr)) { + return MolangParser.parser(reader).parseAll(); + } catch (final ParseException e) { + throw e; + } catch (final IOException e) { + throw new AssertionError("StringReader IOException", e); + } + } + + public static void assertCreateSameTree(final @NotNull String expr1, final @NotNull String expr2) throws ParseException { + final List expressions1 = parse(expr1); + final List expressions2 = parse(expr2); + assertEquals(expressions1, expressions2, () -> "Expressions:\n\t- " + + expr1 + + "\n\t- " + + expr2 + + "\nGenerated different syntax trees:\n\t- " + + expressions1 + + "\n\t- " + + expressions2); + } + + public static void assertCreateTree(final @NotNull String expr, final @NotNull Expression @NotNull ... expressions) { + assertCreateTree(expr, Arrays.asList(expressions)); + } + + public static void assertCreateTree(final @NotNull String expr, final List expressions) { + final List parsed; + try { + parsed = parse(expr); + } catch (final ParseException e) { + fail("Failed to parse expression: '" + expr + "'", e); + return; + } + + { // Network round-trip + ByteBuf buf = Unpooled.buffer(); + ExprBytesUtils.writeExpressions(expressions, buf); + + List readed = ExprBytesUtils.readExpressions(buf); + buf.release(); + + assertEquals(readed, expressions); + } + + assertEquals( + expressions, + parsed, + () -> "Expression: '" + expr + "' generated unexpected syntax tree:\n\t" + + "- Expected: " + expressions + "\n\t" + + "- Got: " + parsed + ); + } + + public static void assertParseError(final @NotNull String expr, final int column) { + try { + final List expressions = parse(expr); + fail("Expected parse error at column " + column + " for expression: '" + expr + "', instead, it was parsed as: " + expressions); + } catch (final ParseException e) { + assertEquals(column, e.cursor().column(), "Expected parse error at column " + column + " for expression: '" + expr + "'"); + } + } +} diff --git a/src/test/java/team/unnamed/mocha/parser/StringTest.java b/parser/src/test/java/team/unnamed/mocha/parser/StringTest.java similarity index 91% rename from src/test/java/team/unnamed/mocha/parser/StringTest.java rename to parser/src/test/java/team/unnamed/mocha/parser/StringTest.java index c2d3187..9361374 100644 --- a/src/test/java/team/unnamed/mocha/parser/StringTest.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/StringTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; import team.unnamed.mocha.util.ExpressionListUtils; import java.io.IOException; @@ -36,10 +35,10 @@ public class StringTest { private static void testToString(String expr) throws IOException { System.out.println("expr " + expr); - String original = ExpressionListUtils.toString(MochaEngine.createStandard().parse(expr)); + String original = ExpressionListUtils.toString(MolangParser.parseAll(expr)); System.out.println("original " + original); - String parsed = ExpressionListUtils.toString(MochaEngine.createStandard().parse(original)); + String parsed = ExpressionListUtils.toString(MolangParser.parseAll(original)); System.out.println("parsed " + parsed); System.out.flush(); diff --git a/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java b/parser/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java similarity index 96% rename from src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java rename to parser/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java index 0b4a024..c90b592 100644 --- a/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java @@ -28,7 +28,7 @@ import java.util.Collections; -import static team.unnamed.mocha.MochaAssertions.assertCreateTree; +import static team.unnamed.mocha.parser.ParserAssertions.assertCreateTree; class TernaryParseTest { @Test diff --git a/runtime-compiler/build.gradle b/runtime-compiler/build.gradle new file mode 100644 index 0000000..d9cc89e --- /dev/null +++ b/runtime-compiler/build.gradle @@ -0,0 +1,24 @@ +plugins { + id "org.jetbrains.kotlin.jvm" +} + +dependencies { + api project(":runtime") + + testImplementation("org.jetbrains.kotlin:kotlin-stdlib:2.3.21") +} + +tasks.register('generateExpectations', Exec) { + workingDir = rootProject.projectDir + def nvmDir = file("${System.getenv('HOME')}/.nvm/versions/node") + executable nvmDir.isDirectory() ? "${nvmDir.listFiles().sort().last()}/bin/node" : 'node' + args 'scripts/generate_expectations.js' +} + +tasks.named("compileTestKotlin") { + enabled = true +} + +tasks.named("test") { + dependsOn tasks.named("generateExpectations") +} diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/MochaEngine.java b/runtime-compiler/src/main/java/team/unnamed/mocha/MochaEngine.java new file mode 100644 index 0000000..521bab6 --- /dev/null +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/MochaEngine.java @@ -0,0 +1,103 @@ +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import team.unnamed.mocha.parser.MolangParser; +import team.unnamed.mocha.runtime.MolangCompiler; +import team.unnamed.mocha.runtime.MolangInterpreter; +import team.unnamed.mocha.runtime.Scope; + +/** + * Convenience holder that bundles a {@link MolangInterpreter} and a + * {@link MolangCompiler} sharing the same {@link Scope}. + * + *

The engine itself does not implement the parsing / interpreter / compiler + * APIs — those live on {@link MolangParser}, {@link MolangInterpreter} and + * {@link MolangCompiler}, accessed via {@link #interpreter()} and + * {@link #compiler()}. This class only exists so that callers that want both + * can construct them in one go with a shared scope.

+ * + * @since 3.0.0 + */ +public final class MochaEngine { + private final MolangInterpreter interpreter; + private final MolangCompiler compiler; + + public MochaEngine(final @NotNull MolangInterpreter interpreter, final @NotNull MolangCompiler compiler) { + this.interpreter = interpreter; + this.compiler = compiler; + } + + /** + * Builds a {@link MochaEngine} on top of an existing {@link MolangInterpreter}, + * sharing its {@link Scope} and entity with a freshly created + * {@link MolangCompiler}. + * + * @since 5.0.0 + */ + @Contract("_ -> new") + public static @NotNull MochaEngine from(final @NotNull MolangInterpreter interpreter) { + return new MochaEngine<>(interpreter, new MolangCompiler(interpreter.entity(), interpreter.scope())); + } + + @Contract("_ -> new") + public static @NotNull MochaEngine create(final T entity) { + return from(MolangInterpreter.create(entity)); + } + + @Contract("-> new") + public static @NotNull MochaEngine create() { + return from(MolangInterpreter.create()); + } + + /** + * Creates a {@link MochaEngine} pre-populated with the standard + * {@code math} / {@code variable} / {@code v} bindings. + * + * @since 3.0.0 + */ + @Contract("_ -> new") + public static @NotNull MochaEngine createStandard(final T entity) { + return from(MolangInterpreter.standard(entity)); + } + + @Contract("-> new") + public static @NotNull MochaEngine createStandard() { + return from(MolangInterpreter.standard()); + } + + public @NotNull MolangInterpreter interpreter() { + return interpreter; + } + + public @NotNull MolangCompiler compiler() { + return compiler; + } + + public @NotNull Scope scope() { + return interpreter.scope(); + } +} \ No newline at end of file diff --git a/src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java rename to runtime-compiler/src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java diff --git a/src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java rename to runtime-compiler/src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java diff --git a/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/MochaFunction.java rename to runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java diff --git a/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java similarity index 76% rename from src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java rename to runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java index 75688be..77e6d8e 100644 --- a/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java @@ -23,15 +23,21 @@ */ package team.unnamed.mocha.runtime; -import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import team.unnamed.mocha.parser.MolangParser; +import team.unnamed.mocha.parser.ParseException; import team.unnamed.mocha.parser.ast.Expression; import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; import team.unnamed.mocha.runtime.compiled.Named; import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; import team.unnamed.mocha.util.ClassFileUtil; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.UncheckedIOException; import java.lang.classfile.ClassFile; import java.lang.constant.ClassDesc; import java.lang.constant.ConstantDescs; @@ -42,6 +48,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Parameter; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; @@ -50,13 +57,13 @@ import static java.util.Objects.requireNonNull; import static team.unnamed.mocha.util.ClassFileUtil.classDescOf; -@ApiStatus.Internal public final class MolangCompiler { private static final AtomicLong CLASS_NAME_COUNTER = new AtomicLong(); private final Object entity; private final Scope scope; private Consumer postCompile; + private Consumer<@NotNull ParseException> parseExceptionHandler; public MolangCompiler(final @Nullable Object entity, final @NotNull Scope scope) { this.entity = entity; @@ -67,8 +74,37 @@ public MolangCompiler(final @Nullable Object entity, final @NotNull Scope scope) return entity; } - public void postCompile(final @Nullable Consumer postCompile) { + /** + * Sets the post-compile function, called after a script is compiled to a + * new class but before the class is loaded. The argument is the class + * bytecode, useful for writing it to a file for debugging. + * + *

By default this is null.

+ * + * @return This compiler instance. + * @since 3.0.0 + */ + @Contract("_ -> this") + public @NotNull MolangCompiler postCompile(final @Nullable Consumer postCompile) { this.postCompile = postCompile; + return this; + } + + /** + * Sets the {@link ParseException} handler. Called whenever an internal + * call to {@link MolangParser} from {@link #compile(Reader, Class)} or + * its overloads fails. After the handler runs, the offending compile + * call falls back to compiling an empty body. + * + *

By default this is null.

+ * + * @return This compiler instance. + * @since 3.0.0 + */ + @Contract("_ -> this") + public @NotNull MolangCompiler handleParseExceptions(final @Nullable Consumer<@NotNull ParseException> exceptionHandler) { + this.parseExceptionHandler = exceptionHandler; + return this; } public @NotNull T compile(final @NotNull List expressions, final @NotNull Class clazz) { @@ -277,4 +313,63 @@ public void postCompile(final @Nullable Consumer postCompile) } return clazz.cast(instance); } + + /** + * Parses {@code reader} and compiles the resulting AST into the given + * {@code interfaceType}. Parse errors are routed through + * {@link #handleParseExceptions(Consumer)}; on a parse failure the + * compiler falls back to compiling an empty body. + * + * @since 3.0.0 + */ + public @NotNull T compile(final @NotNull Reader reader, final @NotNull Class interfaceType) { + List parsed; + try { + parsed = MolangParser.parseAll(reader); + } catch (final ParseException e) { + if (parseExceptionHandler != null) parseExceptionHandler.accept(e); + parsed = Collections.emptyList(); + } catch (final IOException e) { + throw new UncheckedIOException("Failed to read from given reader", e); + } + return compile(parsed, interfaceType); + } + + /** + * @see #compile(Reader, Class) + * @since 3.0.0 + */ + public @NotNull T compile(final @NotNull String code, final @NotNull Class interfaceType) { + requireNonNull(code, "code"); + try (final StringReader reader = new StringReader(code)) { + return compile(reader, interfaceType); + } + } + + /** + * Compiles the given expressions into a no-arg {@link MochaFunction}. + * + * @since 4.0.4 + */ + public @NotNull MochaFunction compile(final @NotNull List expressions) { + return compile(expressions, MochaFunction.class); + } + + /** + * Parses {@code reader} and compiles the resulting AST into a no-arg + * {@link MochaFunction}. + * + * @since 3.0.0 + */ + public @NotNull MochaFunction compile(final @NotNull Reader reader) { + return compile(reader, MochaFunction.class); + } + + /** + * @see #compile(Reader) + * @since 3.0.0 + */ + public @NotNull MochaFunction compile(final @NotNull String code) { + return compile(code, MochaFunction.class); + } } diff --git a/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java rename to runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java diff --git a/src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java rename to runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java diff --git a/src/main/java/team/unnamed/mocha/runtime/compiled/Named.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/Named.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/compiled/Named.java rename to runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/Named.java diff --git a/src/main/java/team/unnamed/mocha/util/ClassFileUtil.java b/runtime-compiler/src/main/java/team/unnamed/mocha/util/ClassFileUtil.java similarity index 100% rename from src/main/java/team/unnamed/mocha/util/ClassFileUtil.java rename to runtime-compiler/src/main/java/team/unnamed/mocha/util/ClassFileUtil.java diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java b/runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java new file mode 100644 index 0000000..5337f70 --- /dev/null +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java @@ -0,0 +1,56 @@ +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha; + +import org.jetbrains.annotations.NotNull; + +import java.util.function.UnaryOperator; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public final class MochaAssertions { + private MochaAssertions() { + throw new UnsupportedOperationException("This class cannot be instantiated"); + } + + public static void assertEvaluates(final double expected, final @NotNull String expr, final @NotNull UnaryOperator> configurer) { + MochaEngine engine = MochaEngine.createStandard(); + engine = configurer.apply(engine); + final double result = engine.interpreter().eval(expr); + assertEquals(expected, result, 0.0001, () -> "Expression: '" + expr + "' evaluated to " + result + ", expected " + expected); + } + + public static void assertEvaluates(final double expected, final @NotNull String expr) { + assertEvaluates(expected, expr, engine -> engine); + } + + public static void assertEvaluatesAndCompiles(final double expected, final @NotNull String expr) { + final MochaEngine engine = MochaEngine.createStandard(); + final double result = engine.interpreter().eval(expr); + assertEquals(expected, result, 0.0001, () -> "(Interpreted) expression: '" + expr + "' evaluated to " + result + ", expected " + expected); + + final double compiledResult = engine.compiler().compile(expr).evaluate(); + assertEquals(expected, compiledResult, 0.0001, () -> "(Compiled) expression: '" + expr + "' evaluated to " + compiledResult + ", expected " + expected); + } +} diff --git a/src/test/java/team/unnamed/mocha/runtime/ArrayAccessRuntimeTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ArrayAccessRuntimeTest.java similarity index 97% rename from src/test/java/team/unnamed/mocha/runtime/ArrayAccessRuntimeTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ArrayAccessRuntimeTest.java index fba71d8..bf22c1a 100644 --- a/src/test/java/team/unnamed/mocha/runtime/ArrayAccessRuntimeTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ArrayAccessRuntimeTest.java @@ -35,7 +35,7 @@ class ArrayAccessRuntimeTest { @Test void test() { final UnaryOperator> configurer = engine -> { - engine.bind(QueryImpl.class); + engine.interpreter().bind(QueryImpl.class); return engine; }; diff --git a/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java similarity index 90% rename from src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java index d28f339..f63c4b4 100644 --- a/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java @@ -31,7 +31,7 @@ class BreakContinueTest { @Test void test_break() { - final float value = MochaEngine.createStandard().eval(String.join("\n", + final float value = MochaEngine.createStandard().interpreter().eval(String.join("\n", "t.i = 0;", "loop(10, {", " t.i = t.i + 1;", @@ -44,7 +44,7 @@ void test_break() { @Test void test_continue() { - final float value = MochaEngine.createStandard().eval( + final float value = MochaEngine.createStandard().interpreter().eval( "t.i = 0;" + "t.sum = 0;" + "loop(20, {" + diff --git a/src/test/java/team/unnamed/mocha/runtime/BytecodeKotlinTest.kt b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BytecodeKotlinTest.kt similarity index 63% rename from src/test/java/team/unnamed/mocha/runtime/BytecodeKotlinTest.kt rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BytecodeKotlinTest.kt index f3feccf..4a0194a 100644 --- a/src/test/java/team/unnamed/mocha/runtime/BytecodeKotlinTest.kt +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BytecodeKotlinTest.kt @@ -22,34 +22,34 @@ class BytecodeTest { val engine = MochaEngine.createStandard() val plain = NoArgument(0) - engine.bindInstance(NoArgument::class.java, plain, "plain") + engine.interpreter().bindInstance(NoArgument::class.java, plain, "plain") val plainExpr = "plain.calc()" - val plainInterpreted = engine.prepareEval(plainExpr) + val plainInterpreted = engine.interpreter().prepareEval(plainExpr) plain.offset = 3 - println(plainInterpreted.evaluate()) + println(plainInterpreted.get()) plain.offset = 4 - println(plainInterpreted.evaluate()) + println(plainInterpreted.get()) - val plainCompiled = engine.compile(plainExpr) + val plainCompiled = engine.compiler().compile(plainExpr) plain.offset = 3 println(plainCompiled.evaluate()) plain.offset = 4 println(plainCompiled.evaluate()) val offset = WithOffset(0) - engine.bindInstance(WithOffset::class.java, offset, "offset") + engine.interpreter().bindInstance(WithOffset::class.java, offset, "offset") val offsetExpr = "offset.calc(1)" - val offsetInterpreted = engine.prepareEval(offsetExpr) + val offsetInterpreted = engine.interpreter().prepareEval(offsetExpr) offset.offset = 3 - println(offsetInterpreted.evaluate()) + println(offsetInterpreted.get()) offset.offset = 4 - println(offsetInterpreted.evaluate()) + println(offsetInterpreted.get()) - val offsetCompiled = engine.compile(offsetExpr) + val offsetCompiled = engine.compiler().compile(offsetExpr) offset.offset = 3 println(offsetCompiled.evaluate()) offset.offset = 4 diff --git a/src/test/java/team/unnamed/mocha/runtime/CaseSensitivityTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CaseSensitivityTest.java similarity index 100% rename from src/test/java/team/unnamed/mocha/runtime/CaseSensitivityTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CaseSensitivityTest.java diff --git a/src/test/java/team/unnamed/mocha/runtime/CompareTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CompareTest.java similarity index 94% rename from src/test/java/team/unnamed/mocha/runtime/CompareTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CompareTest.java index 45487b4..01af59b 100644 --- a/src/test/java/team/unnamed/mocha/runtime/CompareTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CompareTest.java @@ -79,7 +79,7 @@ private static void compare(String expectationsName, String sourceName) throws I float expectedValue = Float.parseFloat(expected); // eval expression - final float result = ENGINE.eval(expression); + final float result = ENGINE.interpreter().eval(expression); Assertions.assertEquals( expectedValue, result, @@ -89,7 +89,7 @@ private static void compare(String expectationsName, String sourceName) throws I // compile and eval expression try { - final float compileResult = ENGINE.compile(expression).evaluate(); + final float compileResult = ENGINE.compiler().compile(expression).evaluate(); Assertions.assertEquals( expectedValue, compileResult, diff --git a/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java similarity index 91% rename from src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java index b83f06a..eda644b 100644 --- a/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java @@ -29,6 +29,6 @@ class ConstantValuesTest { @Test void test() { - MochaEngine.createStandard().compile("math.abs(-5) + math.abs(5) + math.sqrt(25)"); + MochaEngine.createStandard().compiler().compile("math.abs(-5) + math.abs(5) + math.sqrt(25)"); } } diff --git a/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java similarity index 97% rename from src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java index 3b9bb52..6c074b8 100644 --- a/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java @@ -92,7 +92,7 @@ public void test() throws IOException { } return null; }); - final double result = engine.eval(code); + final double result = engine.interpreter().eval(code); assertEquals(expected, out.toString()); assertEquals(89D, result); diff --git a/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java similarity index 93% rename from src/test/java/team/unnamed/mocha/runtime/ForEachTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java index 3c5f886..84fbefc 100644 --- a/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java @@ -40,9 +40,9 @@ void test() { "return v.sum;"); final MochaEngine engine = MochaEngine.createStandard(); - engine.bind(QueryImpl.class); + engine.interpreter().bind(QueryImpl.class); - final double result = engine.eval(code); + final double result = engine.interpreter().eval(code); assertEquals(98, result); } diff --git a/src/test/java/team/unnamed/mocha/runtime/IndividualScopeTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IndividualScopeTest.java similarity index 89% rename from src/test/java/team/unnamed/mocha/runtime/IndividualScopeTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IndividualScopeTest.java index 862e89d..bac8fa7 100644 --- a/src/test/java/team/unnamed/mocha/runtime/IndividualScopeTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IndividualScopeTest.java @@ -39,10 +39,10 @@ public class IndividualScopeTest { @Test public void testThis() { final MochaEngine engine = MochaEngine.createStandard(); - Assertions.assertEquals(0F, engine.eval(THIS)); - Assertions.assertEquals(10F, engine.eval(THIS, scope -> + Assertions.assertEquals(0F, engine.interpreter().eval(THIS)); + Assertions.assertEquals(10F, engine.interpreter().eval(THIS, scope -> scope.set("this", NumberValue.of(10F)) )); - Assertions.assertEquals(0F, engine.eval(THIS)); + Assertions.assertEquals(0F, engine.interpreter().eval(THIS)); } } diff --git a/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java similarity index 86% rename from src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java index 1871a4e..7ef7416 100644 --- a/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java @@ -31,9 +31,9 @@ class InstanceMethodBindingTest { @Test void test() { final MochaEngine engine = MochaEngine.createStandard(); - engine.bindInstance(TestInstanceMethods.class, new TestInstanceMethods("UnnamedTeam"), "instance"); - engine.eval("instance.print_name()"); - engine.compile("instance.print_name()").evaluate(); + engine.interpreter().bindInstance(TestInstanceMethods.class, new TestInstanceMethods("UnnamedTeam"), "instance"); + engine.interpreter().eval("instance.print_name()"); + engine.compiler().compile("instance.print_name()").evaluate(); } public static final class TestInstanceMethods { diff --git a/src/test/java/team/unnamed/mocha/runtime/IntCompiledFunctionTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IntCompiledFunctionTest.java similarity index 96% rename from src/test/java/team/unnamed/mocha/runtime/IntCompiledFunctionTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IntCompiledFunctionTest.java index 60208af..a521ded 100644 --- a/src/test/java/team/unnamed/mocha/runtime/IntCompiledFunctionTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IntCompiledFunctionTest.java @@ -33,7 +33,7 @@ class IntCompiledFunctionTest { @Test void test() throws Exception { - final IntFunction function = MochaEngine.createStandard().compile("math.mod(value / 20, 3)", IntFunction.class); + final IntFunction function = MochaEngine.createStandard().compiler().compile("math.mod(value / 20, 3)", IntFunction.class); assertEquals(0, function.get(0)); assertEquals(1, function.get(20)); diff --git a/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java similarity index 85% rename from src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java index 332edee..0e6a135 100644 --- a/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java @@ -37,12 +37,12 @@ class ParseErrorTest { @Test void test() { final MochaEngine engine = MochaEngine.createStandard(); - engine.bind(QueryImpl.class); + engine.interpreter().bind(QueryImpl.class); - engine.handleParseExceptions(e -> assertEquals("Found error token: Unexpected token '\"', expected single quote (') to start a string literal\n\tat line 1, column 11", e.getMessage())); + engine.interpreter().handleParseExceptions(e -> assertEquals("Found error token: Unexpected token '\"', expected single quote (') to start a string literal\n\tat line 1, column 11", e.getMessage())); // should error since strings only allow single quotes - engine.eval("query.log(\"Hello world!\");"); + engine.interpreter().eval("query.log(\"Hello world!\");"); } @Binding({"query", "q"}) diff --git a/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java similarity index 93% rename from src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java index d246f3a..ff1ccee 100644 --- a/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java @@ -44,10 +44,10 @@ void test() { new Player(world, 0, "Zombie"); final MochaEngine engine = MochaEngine.createStandard(self); - engine.bind(QueryImpl.class); + engine.interpreter().bind(QueryImpl.class); engine.scope().set("self", new JavaValue(self)); - final float result = engine.eval( + final float result = engine.interpreter().eval( "v.result = 0;\n" + "for_each(t.nearby, self->q.get_nearby_entities(5), {\n" + " v.result = v.result + t.nearby->q.get_location();\n" @@ -57,7 +57,7 @@ void test() { assertEquals(17F, result); - final float result2 = engine.eval( + final float result2 = engine.interpreter().eval( "v.result = 0;\n" + "for_each(t.nearby, self->q.get_nearby_entities(500), {\n" // Same code but 500 instead of 5 + " v.result = v.result + t.nearby->q.get_location();\n" diff --git a/src/test/java/team/unnamed/mocha/runtime/arrow/Player.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/Player.java similarity index 100% rename from src/test/java/team/unnamed/mocha/runtime/arrow/Player.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/Player.java diff --git a/src/test/java/team/unnamed/mocha/runtime/arrow/World.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/World.java similarity index 100% rename from src/test/java/team/unnamed/mocha/runtime/arrow/World.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/World.java diff --git a/src/test/java/team/unnamed/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java similarity index 87% rename from src/test/java/team/unnamed/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java index 7ec9dcf..d4a48ca 100644 --- a/src/test/java/team/unnamed/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java @@ -44,7 +44,7 @@ void test() { // 7: goto 11 // 10: iconst_1 // 11: ireturn - final ComparisonFunction gt = engine.compile("a > b", ComparisonFunction.class); + final ComparisonFunction gt = engine.compiler().compile("a > b", ComparisonFunction.class); assertTrue(gt.compare(10, 5)); assertFalse(gt.compare(-50, -20)); assertFalse(gt.compare(3F, 3F)); @@ -59,7 +59,7 @@ void test() { // 7: goto 11 // 10: iconst_1 // 11: ireturn - final ComparisonFunction lt = engine.compile("a < b", ComparisonFunction.class); + final ComparisonFunction lt = engine.compiler().compile("a < b", ComparisonFunction.class); assertFalse(lt.compare(10, 5)); assertTrue(lt.compare(-50, -20)); assertFalse(lt.compare(3F, 3F)); @@ -74,7 +74,7 @@ void test() { // 7: goto 11 // 10: iconst_1 // 11: ireturn - final ComparisonFunction gte = engine.compile("a >= b", ComparisonFunction.class); + final ComparisonFunction gte = engine.compiler().compile("a >= b", ComparisonFunction.class); assertTrue(gte.compare(10, 5)); assertFalse(gte.compare(-50, -20)); assertTrue(gte.compare(3F, 3F)); @@ -89,7 +89,7 @@ void test() { // 7: goto 11 // 10: iconst_1 // 11: ireturn - final ComparisonFunction lte = engine.compile("a <= b", ComparisonFunction.class); + final ComparisonFunction lte = engine.compiler().compile("a <= b", ComparisonFunction.class); assertFalse(lte.compare(10, 5)); assertTrue(lte.compare(-50, -20)); assertTrue(lte.compare(3F, 3F)); @@ -104,7 +104,7 @@ void test() { // 7: goto 11 // 10: iconst_1 // 11: ireturn - final ComparisonFunction eq = engine.compile("a == b", ComparisonFunction.class); + final ComparisonFunction eq = engine.compiler().compile("a == b", ComparisonFunction.class); assertFalse(eq.compare(10, 5)); assertFalse(eq.compare(-50, -20)); assertTrue(eq.compare(3F, 3F)); @@ -119,7 +119,7 @@ void test() { // 7: goto 11 // 10: iconst_1 // 11: ireturn - final ComparisonFunction neq = engine.compile("a != b", ComparisonFunction.class); + final ComparisonFunction neq = engine.compiler().compile("a != b", ComparisonFunction.class); assertTrue(neq.compare(10, 5)); assertTrue(neq.compare(-50, -20)); assertFalse(neq.compare(3F, 3F)); @@ -135,7 +135,7 @@ void test() { // 7: goto 11 // 10: lconst_1 // 11: lreturn - final StupidLongComparisonFunction gt = engine.compile("a > b", StupidLongComparisonFunction.class); + final StupidLongComparisonFunction gt = engine.compiler().compile("a > b", StupidLongComparisonFunction.class); assertEquals(1L, gt.compare(10, 5)); assertEquals(0L, gt.compare(-50, -20)); assertEquals(0L, gt.compare(3F, 3F)); diff --git a/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java similarity index 92% rename from src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java index 9cd32f5..1e4d517 100644 --- a/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java @@ -45,7 +45,7 @@ void test() { // 9: goto +4 (13) // 12: iconst_0 // 13: ireturn - final LogicalFunction and = engine.compile("a && b", LogicalFunction.class); + final LogicalFunction and = engine.compiler().compile("a && b", LogicalFunction.class); assertTrue(and.apply(true, true)); assertFalse(and.apply(true, false)); assertFalse(and.apply(false, true)); @@ -61,7 +61,7 @@ void test() { // 9: goto +4 (13) // 12: iconst_0 // 13: ireturn - final LogicalFunction or = engine.compile("a || b", LogicalFunction.class); + final LogicalFunction or = engine.compiler().compile("a || b", LogicalFunction.class); assertTrue(or.apply(true, true)); assertTrue(or.apply(true, false)); assertTrue(or.apply(false, true)); diff --git a/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java similarity index 90% rename from src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java index 0e85a99..f158713 100644 --- a/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java @@ -38,7 +38,7 @@ void test() { // 0: dload_1 // 1: invokestatic // 4: dreturn - final MathFunction cos = engine.compile("math.cos(x)", MathFunction.class); + final MathFunction cos = engine.compiler().compile("math.cos(x)", MathFunction.class); assertEquals(1F, cos.apply(0), 0.0001); assertEquals(4F / 5D, cos.apply(37), 0.01); assertEquals(3F / 5D, cos.apply(53), 0.01); @@ -50,7 +50,7 @@ void test() { // 1: invokestatic // 4: l2d // 5: dreturn - final MathFunction round = engine.compile("math.round(x)", MathFunction.class); + final MathFunction round = engine.compiler().compile("math.round(x)", MathFunction.class); assertEquals(5.0F, round.apply(5.4F)); assertEquals(6.0F, round.apply(5.5F)); assertEquals(6.0F, round.apply(5.6F)); diff --git a/src/test/java/team/unnamed/mocha/runtime/jvm/MolangCompilerTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MolangCompilerTest.java similarity index 83% rename from src/test/java/team/unnamed/mocha/runtime/jvm/MolangCompilerTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MolangCompilerTest.java index 6667a9e..28338e0 100644 --- a/src/test/java/team/unnamed/mocha/runtime/jvm/MolangCompilerTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MolangCompilerTest.java @@ -34,22 +34,22 @@ public class MolangCompilerTest { @Test void test() { final MochaEngine engine = MochaEngine.createStandard(); - final ScriptType script = engine.compile("false ? a : b", ScriptType.class); + final ScriptType script = engine.compiler().compile("false ? a : b", ScriptType.class); assertEquals(2, script.eval(1, 2)); assertEquals(50, script.eval(20, 50)); assertEquals(200, script.eval(50, 200)); - final ScriptType script2 = engine.compile("a + (b - a) * 0.5", ScriptType.class); + final ScriptType script2 = engine.compiler().compile("a + (b - a) * 0.5", ScriptType.class); assertEquals(5, script2.eval(1, 10)); assertEquals(20, script2.eval(20, 20)); assertEquals(50, script2.eval(-50, 150)); - final ScriptType script3 = engine.compile("(a > b) ? a : b", ScriptType.class); + final ScriptType script3 = engine.compiler().compile("(a > b) ? a : b", ScriptType.class); assertEquals(10, script3.eval(10, 5)); assertEquals(50, script3.eval(50, -20)); assertEquals(3, script3.eval(3F, 3F)); - final ScriptType script4 = engine.compile("(a < b) ? a : b", ScriptType.class); + final ScriptType script4 = engine.compiler().compile("(a < b) ? a : b", ScriptType.class); assertEquals(5, script4.eval(10, 5)); assertEquals(-20, script4.eval(50, -20)); assertEquals(3, script4.eval(3F, 3F)); @@ -59,7 +59,7 @@ void test() { void test_native() { final MochaEngine engine = MochaEngine.createStandard(); //compiler.registerStaticNatives(MolangCompilerTest.class); - System.out.println(engine.compile("3 * math.abs(5 * 5 * -1) + 1").evaluate()); + System.out.println(engine.compiler().compile("3 * math.abs(5 * 5 * -1) + 1").evaluate()); } public interface ScriptType extends MochaCompiledFunction { diff --git a/src/test/java/team/unnamed/mocha/runtime/standart/MochaMathTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/standart/MochaMathTest.java similarity index 94% rename from src/test/java/team/unnamed/mocha/runtime/standart/MochaMathTest.java rename to runtime-compiler/src/test/java/team/unnamed/mocha/runtime/standart/MochaMathTest.java index da4f762..aa96a8b 100644 --- a/src/test/java/team/unnamed/mocha/runtime/standart/MochaMathTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/standart/MochaMathTest.java @@ -31,6 +31,6 @@ public class MochaMathTest { @Test void test() { final MochaEngine engine = MochaEngine.createStandard(); - Assertions.assertEquals(Math.abs(-10F), engine.eval("math.abs(-10);")); + Assertions.assertEquals(Math.abs(-10F), engine.interpreter().eval("math.abs(-10);")); } } diff --git a/src/test/resources/expectations.txt b/runtime-compiler/src/test/resources/expectations.txt similarity index 100% rename from src/test/resources/expectations.txt rename to runtime-compiler/src/test/resources/expectations.txt diff --git a/src/test/resources/tests.txt b/runtime-compiler/src/test/resources/tests.txt similarity index 100% rename from src/test/resources/tests.txt rename to runtime-compiler/src/test/resources/tests.txt diff --git a/runtime/build.gradle b/runtime/build.gradle new file mode 100644 index 0000000..7bf1905 --- /dev/null +++ b/runtime/build.gradle @@ -0,0 +1,3 @@ +dependencies { + api project(":parser") +} diff --git a/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java b/runtime/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java diff --git a/src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java b/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java diff --git a/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java b/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java diff --git a/src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java b/runtime/src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java diff --git a/src/main/java/team/unnamed/mocha/runtime/JavaTypes.java b/runtime/src/main/java/team/unnamed/mocha/runtime/JavaTypes.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/JavaTypes.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/JavaTypes.java diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java b/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java new file mode 100644 index 0000000..16b1354 --- /dev/null +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java @@ -0,0 +1,394 @@ +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import team.unnamed.mocha.parser.MolangParser; +import team.unnamed.mocha.parser.ParseException; +import team.unnamed.mocha.parser.ast.Expression; +import team.unnamed.mocha.parser.ast.FloatExpression; +import team.unnamed.mocha.runtime.binding.Binding; +import team.unnamed.mocha.runtime.binding.JavaObjectBinding; +import team.unnamed.mocha.runtime.standard.MochaMath; +import team.unnamed.mocha.runtime.value.MutableObjectBinding; +import team.unnamed.mocha.runtime.value.NumberValue; +import team.unnamed.mocha.runtime.value.ObjectValue; +import team.unnamed.mocha.runtime.value.Value; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.UncheckedIOException; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import static java.util.Objects.requireNonNull; + +/** + * Stateful entry point for interpretation. Holds the entity, the global + * {@link Scope} and the runtime-side configuration (parse exception handler, + * "warn on reflective function usage" flag), and exposes {@code eval(...)} / + * {@code prepareEval(...)} variants plus binding helpers. + * + *

Each {@code eval} call gets its own copy of the scope with a fresh + * {@code temp} / {@code t} binding so concurrent or nested evaluations do + * not see each other's local state.

+ * + * @since 5.0.0 + */ +public final class MolangInterpreter { + private final T entity; + private final Scope scope; + private Consumer<@NotNull ParseException> parseExceptionHandler; + private boolean warnOnReflectiveFunctionUsage; + + public MolangInterpreter(final @Nullable T entity, final @NotNull Scope scope) { + this.entity = entity; + this.scope = requireNonNull(scope, "scope"); + } + + /** + * Creates an interpreter with the given {@code entity} and an empty, + * user-built {@link Scope}. + * + * @since 5.0.0 + */ + @Contract("_, _ -> new") + public static @NotNull MolangInterpreter create(final @Nullable T entity, final @NotNull Consumer scopeBuilder) { + final Scope.Builder builder = Scope.builder(); + scopeBuilder.accept(builder); + return new MolangInterpreter<>(entity, builder.build()); + } + + @Contract("_ -> new") + public static @NotNull MolangInterpreter create(final @Nullable T entity) { + return create(entity, b -> { + }); + } + + @Contract("-> new") + public static @NotNull MolangInterpreter create() { + return create(null); + } + + /** + * Creates an interpreter pre-populated with the standard + * {@code math} / {@code variable} / {@code v} bindings. Lives in the + * runtime module so a caller that only needs interpretation does not have + * to depend on the compiler module. + * + * @since 5.0.0 + */ + @Contract("_ -> new") + public static @NotNull MolangInterpreter standard(final @Nullable T entity) { + return create(entity, builder -> { + builder.set("math", JavaObjectBinding.of(MochaMath.class, null, new MochaMath())); + final MutableObjectBinding variableBinding = new MutableObjectBinding(); + builder.set("variable", variableBinding); + builder.set("v", variableBinding); + }); + } + + @Contract("-> new") + public static @NotNull MolangInterpreter standard() { + return standard(null); + } + + public @Nullable T entity() { + return entity; + } + + /** + * Returns the bindings for this interpreter instance. + * + * @since 3.0.0 + */ + public @NotNull Scope scope() { + return scope; + } + + //#region INTERPRETER API + + /** + * Evaluates the given {@code expressions}, these expressions are already + * parsed and are interpreted as fast as possible. + * + * @param expressions The expressions to evaluate. + * @param scopeConsumer Optional callback to populate per-call bindings on + * the local scope copy before evaluation. + * @return The result of the evaluation. + * @since 4.1.0 + */ + public float eval(final @NotNull List expressions, final @Nullable Consumer scopeConsumer) { + if (expressions.size() == 1 && expressions.get(0) instanceof FloatExpression expression) { + return expression.value(); + } + + final Scope local = scope.copy(); + { + final MutableObjectBinding temp = new MutableObjectBinding(); + local.set("temp", temp); + local.set("t", temp); + } + if (scopeConsumer != null && !local.readOnly()) scopeConsumer.accept(local); + local.readOnly(true); + + final ExpressionInterpreter evaluator = new ExpressionInterpreter<>(entity, local); + evaluator.warnOnReflectiveFunctionUsage(warnOnReflectiveFunctionUsage); + Value lastResult = NumberValue.zero(); + + for (final Expression expression : expressions) { + lastResult = expression.visit(evaluator); + final Value returnValue = evaluator.popReturnValue(); + if (returnValue != null) { + lastResult = returnValue; + break; + } + } + + return lastResult == null ? 0F : lastResult.getAsNumber(); + } + + /** + * @see #eval(List, Consumer) + * @since 3.0.0 + */ + public float eval(final @NotNull List expressions) { + return eval(expressions, null); + } + + /** + * Parses and evaluates the given Molang source. + * + *

Note that this method does not cache parsed expressions. If you want + * to re-use parsed expressions, parse them yourself with + * {@link MolangParser} and use {@link #eval(List, Consumer)}.

+ * + *

Parse errors are routed through the handler set by + * {@link #handleParseExceptions(Consumer)} and the call returns {@code 0}.

+ * + * @since 4.1.0 + */ + public float eval(final @NotNull Reader source, final @Nullable Consumer scopeConsumer) { + final List parsed; + try { + parsed = MolangParser.parseAll(source); + } catch (final ParseException e) { + if (parseExceptionHandler != null) parseExceptionHandler.accept(e); + return 0F; + } catch (final IOException e) { + throw new UncheckedIOException("Failed to read from given reader", e); + } + return eval(parsed, scopeConsumer); + } + + /** + * @see #eval(Reader, Consumer) + * @since 3.0.0 + */ + public float eval(final @NotNull Reader source) { + return eval(source, null); + } + + /** + * Parses and evaluates the given Molang source string. + * + * @see #eval(Reader, Consumer) + * @since 4.1.0 + */ + public float eval(final @NotNull String source, final @Nullable Consumer scopeConsumer) { + requireNonNull(source, "source"); + try (final StringReader reader = new StringReader(source)) { + return eval(reader, scopeConsumer); + } + } + + /** + * @see #eval(String, Consumer) + * @since 3.0.0 + */ + public float eval(final @NotNull String source) { + return eval(source, null); + } + + /** + * Parses {@code reader} once and returns a {@link Supplier} that runs the + * cached AST through the interpreter on each call. Parse errors go through + * {@link #handleParseExceptions(Consumer)}; a failed parse yields a + * supplier that always produces {@code 0}. + * + * @since 4.1.0 + */ + public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull Reader reader, final @Nullable Consumer scopeConsumer) { + final List parsed; + try { + parsed = MolangParser.parseAll(reader); + } catch (final ParseException e) { + if (parseExceptionHandler != null) parseExceptionHandler.accept(e); + return () -> 0F; + } catch (final IOException e) { + throw new UncheckedIOException("Failed to read from given reader", e); + } + return () -> eval(parsed, scopeConsumer); + } + + /** + * @see #prepareEval(Reader, Consumer) + * @since 3.0.0 + */ + public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull Reader reader) { + return prepareEval(reader, null); + } + + /** + * @see #prepareEval(Reader, Consumer) + * @since 4.1.0 + */ + public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull String code, final @Nullable Consumer scopeConsumer) { + requireNonNull(code, "code"); + try (final StringReader reader = new StringReader(code)) { + return prepareEval(reader, scopeConsumer); + } + } + + /** + * @see #prepareEval(String, Consumer) + * @since 3.0.0 + */ + public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull String code) { + return prepareEval(code, null); + } + + //#endregion + + //#region BINDING API + + /** + * Binds the given {@code clazz}'s static fields and methods into this + * interpreter's {@link Scope}. + * + *

Fields and methods are bound in the following format:

+ *
+     *     namespace.field
+     *     namespace.method()
+     *     namespace.method(arg1, arg2)
+     * 
+ * + *

Where {@code namespace} comes from the class' {@link Binding} + * annotation, and field/method names from {@link Binding} annotations on + * the members.

+ * + * @see Binding + * @since 3.0.0 + */ + public void bind(final @NotNull Class clazz) { + final JavaObjectBinding javaObjectBinding = JavaObjectBinding.of(clazz, null, null); + for (final String name : javaObjectBinding.names()) { + scope.set(name, javaObjectBinding); + } + } + + /** + * Binds the given {@code instance}'s non-static fields and methods. + * + *

Fields and methods are bound in the format:

+ *
+     *     name.field
+     *     name.method()
+     *     name.method(arg1, arg2)
+     * 
+ * + *

Where {@code name} comes from the {@code name} parameter, and field + * /method names from {@link Binding} annotations.

+ * + * @param clazz The instance's class (or interface) to use. + * @param instance The instance to bind. + * @param name The name to bind the instance to. + * @param aliases Additional names to bind the instance to. + * @param The instance's type. + * @since 3.0.0 + */ + public void bindInstance(final @NotNull Class clazz, final @NotNull B instance, final @NotNull String name, final @NotNull String @NotNull ... aliases) { + final JavaObjectBinding javaObjectBinding = JavaObjectBinding.of(clazz, instance, null); + scope.set(name, javaObjectBinding); + for (final String alias : aliases) { + scope.set(alias, javaObjectBinding); + } + } + + //#endregion + + //#region CONFIGURATION API + + public boolean warnOnReflectiveFunctionUsage() { + return warnOnReflectiveFunctionUsage; + } + + /** + * Sets the boolean value for the "warn on reflective function usage" + * option. + * + *

When set to true, {@link #eval} may log a warning when evaluating + * code that includes a call to a function that was registered using only + * annotations and therefore has to be invoked via Reflection, taking some + * extra time.

+ * + *

Note that this behavior can be avoided by setting an + * {@link ObjectValue} when binding static or non-static methods and fields.

+ * + *

By default this is false.

+ * + * @return This interpreter instance. + * @since 3.0.0 + */ + @Contract("_ -> this") + public @NotNull MolangInterpreter warnOnReflectiveFunctionUsage(final boolean warnOnReflectiveFunctionUsage) { + this.warnOnReflectiveFunctionUsage = warnOnReflectiveFunctionUsage; + return this; + } + + /** + * Sets the {@link ParseException} handler. This handler will be called + * whenever an internal call to {@link MolangParser} from + * {@link #eval(Reader, Consumer)} or {@link #prepareEval(Reader, Consumer)} + * fails. + * + *

Usually useful for logging/debugging purposes.

+ * + *

By default this is null.

+ * + * @return This interpreter instance. + * @since 3.0.0 + */ + @Contract("_ -> this") + public @NotNull MolangInterpreter handleParseExceptions(final @Nullable Consumer<@NotNull ParseException> exceptionHandler) { + this.parseExceptionHandler = exceptionHandler; + return this; + } + + //#endregion +} diff --git a/src/main/java/team/unnamed/mocha/runtime/Scope.java b/runtime/src/main/java/team/unnamed/mocha/runtime/Scope.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/Scope.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/Scope.java diff --git a/src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java b/runtime/src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java diff --git a/src/main/java/team/unnamed/mocha/runtime/TypeCastException.java b/runtime/src/main/java/team/unnamed/mocha/runtime/TypeCastException.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/TypeCastException.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/TypeCastException.java diff --git a/src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java diff --git a/src/main/java/team/unnamed/mocha/runtime/binding/Binding.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Binding.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/binding/Binding.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/binding/Binding.java diff --git a/src/main/java/team/unnamed/mocha/runtime/binding/Entity.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Entity.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/binding/Entity.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/binding/Entity.java diff --git a/src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java diff --git a/src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java diff --git a/src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java diff --git a/src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java diff --git a/src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java diff --git a/src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java diff --git a/src/main/java/team/unnamed/mocha/runtime/standard/MochaMath.java b/runtime/src/main/java/team/unnamed/mocha/runtime/standard/MochaMath.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/standard/MochaMath.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/standard/MochaMath.java diff --git a/src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java diff --git a/src/main/java/team/unnamed/mocha/runtime/value/Function.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/Function.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/value/Function.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/value/Function.java diff --git a/src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java diff --git a/src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java diff --git a/src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java diff --git a/src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java diff --git a/src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java diff --git a/src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java diff --git a/src/main/java/team/unnamed/mocha/runtime/value/StringValue.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/StringValue.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/value/StringValue.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/value/StringValue.java diff --git a/src/main/java/team/unnamed/mocha/runtime/value/Value.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/Value.java similarity index 100% rename from src/main/java/team/unnamed/mocha/runtime/value/Value.java rename to runtime/src/main/java/team/unnamed/mocha/runtime/value/Value.java diff --git a/src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java b/runtime/src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java similarity index 100% rename from src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java rename to runtime/src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java diff --git a/src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java b/runtime/src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java similarity index 100% rename from src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java rename to runtime/src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java diff --git a/src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java b/runtime/src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java similarity index 100% rename from src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java rename to runtime/src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java diff --git a/scripts/generate_expectations.js b/scripts/generate_expectations.js index 0cbe2d1..7aef030 100755 --- a/scripts/generate_expectations.js +++ b/scripts/generate_expectations.js @@ -13,7 +13,7 @@ const parser = new (require('./lib/molang'))(); // create read/write streams to generate // results -const basePath = 'src/test/resources'; +const basePath = 'runtime-compiler/src/test/resources'; const input = fs.createReadStream(`${basePath}/tests.txt`); const output = fs.createWriteStream(`${basePath}/expectations.txt`); diff --git a/settings.gradle.kts b/settings.gradle.kts index 2338c7b..c7d1e96 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,3 +6,10 @@ pluginManagement { } rootProject.name = "mocha" + +include( + "lexer", + "parser", + "runtime", + "runtime-compiler", +) diff --git a/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java b/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java index 2fbeaef..5a7918e 100644 --- a/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java +++ b/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java @@ -75,7 +75,7 @@ public void prepare() throws Exception { final String expr = "temp.t = 3; return 3*temp.t*temp.t - 2*temp.t*temp.t*temp.t;"; - function = mocha.compile(expr); + function = mocha.compiler().compile(expr); mlExpression = MolangCompiler.create(MolangCompiler.DEFAULT_FLAGS, getClass().getClassLoader()).compile(expr); mlExpressions = MoLang.newParser("temp.t = 3; return 3*temp.t*temp.t - 2*temp.t*temp.t*temp.t;").parse(); } diff --git a/src/main/java/team/unnamed/mocha/MochaEngine.java b/src/main/java/team/unnamed/mocha/MochaEngine.java deleted file mode 100644 index 77f4696..0000000 --- a/src/main/java/team/unnamed/mocha/MochaEngine.java +++ /dev/null @@ -1,458 +0,0 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.ParseException; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.runtime.MochaFunction; -import team.unnamed.mocha.runtime.Scope; -import team.unnamed.mocha.runtime.binding.Binding; -import team.unnamed.mocha.runtime.binding.JavaObjectBinding; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; -import team.unnamed.mocha.runtime.standard.MochaMath; -import team.unnamed.mocha.runtime.value.MutableObjectBinding; -import team.unnamed.mocha.runtime.value.ObjectValue; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.UncheckedIOException; -import java.util.List; -import java.util.function.Consumer; - -import static java.util.Objects.requireNonNull; - -/** - * The engine's entry class. Provides methods to evaluate - * and parse Molang code from strings and readers. - * - * @since 3.0.0 - */ -public interface MochaEngine { - static MochaEngine create(T entity) { - return new MochaEngineImpl<>(entity, b -> { - }); - } - - static MochaEngine create(T entity, Consumer scopeBuilder) { - return new MochaEngineImpl<>(entity, scopeBuilder); - } - - static MochaEngine create() { - return new MochaEngineImpl<>(null, b -> { - }); - } - - /** - * Creates a new, clean and empty {@link MochaEngine} instance - * with the standard, default bindings. - * - * @return The created {@link MochaEngine} instance. - * @since 3.0.0 - */ - @Contract("_ -> new") - static @NotNull MochaEngine createStandard(T entity) { - return create(entity, builder -> { - builder.set("math", JavaObjectBinding.of(MochaMath.class, null, new MochaMath())); - final MutableObjectBinding variableBinding = new MutableObjectBinding(); - builder.set("variable", variableBinding); - builder.set("v", variableBinding); - }); - } - - /** - * Creates a new, clean and empty {@link MochaEngine} instance - * with the standard, default bindings. - * - * @return The created {@link MochaEngine} instance. - * @since 3.0.0 - */ - @Contract("-> new") - static @NotNull MochaEngine createStandard() { - return createStandard(null); - } - - //#region PARSING API - - /** - * Parses the data from the given {@code reader} - * to a {@link List} of {@link Expression} - * - * Note that this method won't close - * the given {@code reader} - * - * @param reader The reader to read the data from - * @return The list of parsed expressions - * @throws ParseException If read failed or there - * are syntax errors in the script - * @since 3.0.0 - */ - @NotNull List parse(final @NotNull Reader reader) throws IOException; - - /** - * Parses the given {@code string} to a list of - * {@link Expression} - * - * @param string The MoLang string - * @return The list of parsed expressions - * @throws ParseException If parsing fails - */ - default @NotNull List parse(final @NotNull String string) throws ParseException { - try (final StringReader reader = new StringReader(string)) { - return parse(reader); - } catch (final ParseException e) { - throw e; - } catch (final IOException e) { - throw new UncheckedIOException("Error occurred reading the source code: '" + string + "'", e); - } - } - - //#endregion END PARSING API - - //#region INTERPRETER API - - /** - * Evaluates the given {@code expressions}, these expressions - * are already parsed and are interpreted as fast as possible. - * - * @param expressions The expressions to evaluate. - * @return The result of the evaluation. - * @since 4.1.0 - */ - float eval(final @NotNull List expressions, final @Nullable Consumer scopeConsumer); - - /** - * See {@link #eval(List, Consumer)} - * @since 3.0.0 - */ - default float eval(final @NotNull List expressions) { - return eval(expressions, null); - } - - /** - * Parses and evaluates the given Molang source. - * - *

Note that the engine instance is not responsible - * for caching parsed expressions, so if you want to - * re-use parsed expressions, you should use the - * {@link #parse(Reader)} and {@link #eval(List, Consumer)} - * methods.

- * - * @param source The source to evaluate. - * @return The result of the evaluation. - * @see #parse(Reader) - * @see #eval(List, Consumer) - * @since 4.1.0 - */ - float eval(final @NotNull Reader source, final @Nullable Consumer scopeConsumer); - - /** - * See {@link #eval(Reader, Consumer)} - * @since 3.0.0 - */ - default float eval(final @NotNull Reader source) { - return eval(source, null); - } - - /** - * Parses and evaluates the given Molang source. - * - *

Note that the engine instance is not responsible - * for caching parsed expressions, so if you want to - * re-use parsed expressions, you should use the - * {@link #parse(String)} and {@link #eval(List, Consumer)} - * methods.

- * - * @param source The source to evaluate. - * @return The result of the evaluation. - * @see #parse(String) - * @see #eval(List, Consumer) - * @since 4.1.0 - */ - default float eval(final @NotNull String source, final @Nullable Consumer scopeConsumer) { - requireNonNull(source, "script"); - try (final StringReader reader = new StringReader(source)) { - return eval(reader, scopeConsumer); - } - } - - /** - * See {@link #eval(String, Consumer)} - * @since 3.0.0 - */ - default float eval(final @NotNull String source) { - return eval(source, null); - } - - /** - * Parses the data from the given {@code reader} and - * returns a cached, interpretable {@link MochaFunction}. - * - *
Note that this method won't close the given
-     * {@code reader}
- * - *

This approach is the same as parsing to a List of - * expressions, caching them and then evaluating using - * {@link #eval(List, Consumer)}, but easier, since it already keeps - * this {@link MochaEngine} instance.

- * - * @param reader The reader to read the data from - * @return The cached, interpretable function - * @since 4.1.0 - */ - @NotNull MochaFunction prepareEval(final @NotNull Reader reader, final @Nullable Consumer scopeConsumer); - - /** - * See {@link #prepareEval(Reader, Consumer)} - * @since 3.0.0 - */ - default @NotNull MochaFunction prepareEval(final @NotNull Reader reader) { - return prepareEval(reader, null); - } - - /** - * Parses the given {@code string} and returns a cached, - * interpretable {@link MochaFunction}. - * - *

This approach is the same as parsing to a List of - * expressions, caching them and then evaluating using - * {@link #eval(List, Consumer)}, but easier, since it already keeps - * this {@link MochaEngine} instance.

- * - * @param string The MoLang string - * @return The cached, interpretable function - * @since 4.1.0 - */ - default @NotNull MochaFunction prepareEval(final @NotNull String string, final @Nullable Consumer scopeConsumer) { - try (final StringReader reader = new StringReader(string)) { - return prepareEval(reader, scopeConsumer); - } - } - - /** - * See {@link #prepareEval(String, Consumer)} - * @since 3.0.0 - */ - default @NotNull MochaFunction prepareEval(final @NotNull String string) { - return prepareEval(string, null); - } - //#endregion END INTERPRETER API - - //#region COMPILING API - - /** - * Compiles the given code into a Molang function - * that can take arguments. - * - * @param reader The code to compile. - * @param interfaceType The interface to implement, must - * have a single method. - * @return The compiled function. - * @since 3.0.0 - */ - @NotNull F compile(final @NotNull Reader reader, final @NotNull Class interfaceType); - - /** - * Compiles the given code into a Molang function - * that can take arguments. - * - * @param expressions The code to compile. - * @param interfaceType The interface to implement, must - * have a single method. - * @return The compiled function. - * @since 4.0.4 - */ - @NotNull F compile(final @NotNull List expressions, final @NotNull Class interfaceType); - - /** - * Compiles the given code into a Molang function - * that can take arguments. - * - * @param code The code to compile. - * @param interfaceType The interface to implement, must - * have a single method. - * @return The compiled function. - * @since 3.0.0 - */ - default @NotNull F compile(final @NotNull String code, final @NotNull Class interfaceType) { - requireNonNull(code, "code"); - try (final StringReader reader = new StringReader(code)) { - return compile(reader, interfaceType); - } - } - - /** - * Compiles the given code into a Molang function - * that takes no arguments. - * - * @param reader The code to compile. - * @return The compiled function. - * @since 3.0.0 - */ - default @NotNull MochaFunction compile(final @NotNull Reader reader) { - return compile(reader, MochaFunction.class); - } - - /** - * Compiles the given code into a Molang function - * that takes no arguments. - * - * @param expressions The code to compile. - * @return The compiled function. - * @since 4.0.4 - */ - default @NotNull MochaFunction compile(final @NotNull List expressions) { - return compile(expressions, MochaFunction.class); - } - - /** - * Compiles the given code into a Molang function - * that takes no arguments. - * - * @param code The code to compile. - * @return The compiled function. - * @since 3.0.0 - */ - default @NotNull MochaFunction compile(final @NotNull String code) { - requireNonNull(code, "code"); - try (final StringReader reader = new StringReader(code)) { - return compile(reader); - } - } - - //#endregion END COMPILING API - - //#region BINDING API - - /** - * Binds the given {@code clazz} static fields and methods. - * - *

Fields and methods are bound in the following format:

- *
-     *     namespace.field
-     *     namespace.method()
-     *     namespace.method(arg1, arg2)
-     * 
- * - *

Where {@code namespace} is given by the given class' - * {@link Binding} annotation, and the field and method - * names are also given by {@link Binding} annotations.

- * - * @param clazz The class to bind. - * @see Binding - * @since 3.0.0 - */ - void bind(final @NotNull Class clazz); - - /** - * Binds the given {@code instance} non-static fields and methods. - * - *

Fields and methods are bound in the following format:

- *
-     *     name.field
-     *     name.method()
-     *     name.method(arg1, arg2)
-     * 
- * - *

Where {@code name} is given by the {@code name} parameter, - * and the field and method names are given by {@link Binding} - * annotations.

- * - * @param clazz The instance's class (or interface) to use. - * @param instance The instance to bind. - * @param name The name to bind the instance to. - * @param aliases The aliases to bind the instance to. - * @param The instance's type. - * @since 3.0.0 - */ - void bindInstance(final @NotNull Class clazz, final @NotNull B instance, final @NotNull String name, final @NotNull String @NotNull ... aliases); - //#endregion - - //#region CONFIGURATION API - - /** - * Sets the boolean value for the "warn on reflective function usage" - * option. - * - *

When set to true, {@link #eval} may log a warning when evaluating - * code that includes a call to a function that was registered using only - * annotations, and for so, has to be called using Reflection, taking some - * extra time.

- * - *

Note that this behavior can be avoided by setting a {@link ObjectValue} - * when binding static or non-static methods and fields

- * - *

By default this is false.

- * - * @param warnOnReflectiveFunctionUsage The new value for the option - * @return This engine instance - * @since 3.0.0 - */ - @Contract("_ -> this") - @NotNull MochaEngine warnOnReflectiveFunctionUsage(final boolean warnOnReflectiveFunctionUsage); - - /** - * Sets the {@link ParseException} handler. This handler will be called - * whenever an internal call to the {@link #parse} method fails. These - * internal calls commonly include interpreting or compiling code. - * - *

Usually useful for logging/debugging purposes.

- * - *

By default this is null.

- * - * @param exceptionHandler The new parse exception handler - * @return This engine instance - * @since 3.0.0 - */ - @Contract("_ -> this") - @NotNull MochaEngine handleParseExceptions(final @Nullable Consumer<@NotNull ParseException> exceptionHandler); - - /** - * Sets the post-compile function, which is called after a script - * is compiled to a new class, and before it is loaded. The received - * argument is the class bytecode, which can be written to a file for - * debugging purposes. - * - *

By default this is set to null.

- * - * @param bytecodeConsumer The new post-compile function - * @return This engine instance - * @since 3.0.0 - */ - @Contract("_ -> this") - @NotNull MochaEngine postCompile(final @Nullable Consumer bytecodeConsumer); - //#endregion - - /** - * Returns the bindings for this Molang engine - * instance. - * - * @return This engine's bindings - * @since 3.0.0 - */ - @NotNull Scope scope(); -} diff --git a/src/main/java/team/unnamed/mocha/MochaEngineImpl.java b/src/main/java/team/unnamed/mocha/MochaEngineImpl.java deleted file mode 100644 index 0e0cef5..0000000 --- a/src/main/java/team/unnamed/mocha/MochaEngineImpl.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.MolangParser; -import team.unnamed.mocha.parser.ParseException; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.parser.ast.FloatExpression; -import team.unnamed.mocha.runtime.ExpressionInterpreter; -import team.unnamed.mocha.runtime.MochaFunction; -import team.unnamed.mocha.runtime.MolangCompiler; -import team.unnamed.mocha.runtime.Scope; -import team.unnamed.mocha.runtime.binding.JavaObjectBinding; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; -import team.unnamed.mocha.runtime.value.MutableObjectBinding; -import team.unnamed.mocha.runtime.value.NumberValue; -import team.unnamed.mocha.runtime.value.Value; - -import java.io.IOException; -import java.io.Reader; -import java.io.UncheckedIOException; -import java.util.Collections; -import java.util.List; -import java.util.function.Consumer; - -final class MochaEngineImpl implements MochaEngine { - private final Scope scope; - private final T entity; - private final MolangCompiler compiler; - - private Consumer<@NotNull ParseException> parseExceptionHandler; - private boolean warnOnReflectiveFunctionUsage; - - public MochaEngineImpl(final T entity, final Consumer scopeBuilder) { - Scope.Builder builder = Scope.builder(); - scopeBuilder.accept(builder); - this.scope = builder.build(); - this.entity = entity; - this.compiler = new MolangCompiler(entity, scope); - } - - @Override - public float eval(final @NotNull List expressions, final @Nullable Consumer scopeConsumer) { - if (expressions.size() == 1 && expressions.get(0) instanceof FloatExpression expression) { - return expression.value(); - } - - // create bindings that just apply for this evaluation - final Scope local = scope.copy(); - { - // create temp bindings - MutableObjectBinding temp = new MutableObjectBinding(); - local.set("temp", temp); - local.set("t", temp); - } - if (scopeConsumer != null && !local.readOnly()) scopeConsumer.accept(local); - local.readOnly(true); - ExpressionInterpreter evaluator = new ExpressionInterpreter<>(entity, local); - evaluator.warnOnReflectiveFunctionUsage(warnOnReflectiveFunctionUsage); - Value lastResult = NumberValue.zero(); - - for (Expression expression : expressions) { - lastResult = expression.visit(evaluator); - Value returnValue = evaluator.popReturnValue(); - if (returnValue != null) { - lastResult = returnValue; - break; - } - } - - // ensure returned value is a number - return lastResult == null ? 0F : lastResult.getAsNumber(); - } - - @Override - public float eval(final @NotNull Reader source, final @Nullable Consumer scopeConsumer) { - final List parsed; - try { - parsed = parse(source); - } catch (final ParseException e) { - // parse errors just output zero - if (parseExceptionHandler != null) { - parseExceptionHandler.accept(e); - } - return 0; - } catch (final IOException e) { - throw new UncheckedIOException("Failed to read from given reader", e); - } - return eval(parsed, scopeConsumer); - } - - @Override - public @NotNull MochaFunction prepareEval(final @NotNull Reader reader, final @Nullable Consumer scopeConsumer) { - final List parsed; - try { - parsed = parse(reader); - } catch (final ParseException e) { - // parse errors just output zero - if (parseExceptionHandler != null) { - parseExceptionHandler.accept(e); - } - return () -> 0F; - } catch (final IOException e) { - throw new UncheckedIOException("Failed to read from given reader", e); - } - return new MochaFunction() { - @Override - public float evaluate() { - return eval(parsed, scopeConsumer); - } - - @Override - public @NotNull String toString() { - return "MochaPreparedFunction(" + parsed + ")"; - } - }; - } - - @Override - public @NotNull MochaFunction prepareEval(final @NotNull String code, final @Nullable Consumer scopeConsumer) { - final List parsed; - try { - parsed = parse(code); - } catch (final ParseException e) { - // parse errors just output zero - if (parseExceptionHandler != null) { - parseExceptionHandler.accept(e); - } - return new MochaFunction() { - @Override - public float evaluate() { - return 0F; - } - - @Override - public @NotNull String toString() { - return "MochaPreparedFunction('" + code + "', " + e.getMessage() + ")"; - } - }; - } - - return new MochaFunction() { - @Override - public float evaluate() { - return eval(parsed, scopeConsumer); - } - - @Override - public @NotNull String toString() { - return "MochaPreparedFunction(" + parsed + ")"; - } - }; - } - - @Override - public @NotNull F compile(final @NotNull Reader reader, final @NotNull Class interfaceType) { - List parsed; - try { - parsed = parse(reader); - } catch (final ParseException e) { - if (parseExceptionHandler != null) { - parseExceptionHandler.accept(e); - } - parsed = Collections.emptyList(); - } catch (final IOException e) { - throw new RuntimeException("Failed to read from given reader", e); - } - return compile(parsed, interfaceType); - } - - @Override - public @NotNull F compile(final @NotNull List parsed, final @NotNull Class interfaceType) { - return compiler.compile(parsed, interfaceType); - } - - @Override - public @NotNull Scope scope() { - return scope; - } - - @Override - public void bind(final @NotNull Class clazz) { - final JavaObjectBinding javaObjectBinding = JavaObjectBinding.of(clazz, null, null); - for (final String name : javaObjectBinding.names()) { - scope.set(name, javaObjectBinding); - } - } - - @Override - public void bindInstance(final @NotNull Class clazz, final @NotNull B instance, final @NotNull String name, final @NotNull String @NotNull ... aliases) { - final JavaObjectBinding javaObjectBinding = JavaObjectBinding.of(clazz, instance, null); - scope.set(name, javaObjectBinding); - for (final String alias : aliases) { - scope.set(alias, javaObjectBinding); - } - } - - @Override - public @NotNull List parse(final @NotNull Reader reader) throws IOException { - return MolangParser.parser(reader).parseAll(); - } - - @Override - public @NotNull MochaEngine warnOnReflectiveFunctionUsage(final boolean warnOnReflectiveFunctionUsage) { - this.warnOnReflectiveFunctionUsage = warnOnReflectiveFunctionUsage; - return this; - } - - @Override - public @NotNull MochaEngine handleParseExceptions(final @Nullable Consumer<@NotNull ParseException> exceptionHandler) { - this.parseExceptionHandler = exceptionHandler; - return this; - } - - @Override - public @NotNull MochaEngine postCompile(final @Nullable Consumer bytecodeConsumer) { - compiler.postCompile(bytecodeConsumer); - return this; - } -} From f32d90a3e97ee68e5265b9b2bb6b7f7ff0008c71 Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sun, 10 May 2026 00:46:42 +0700 Subject: [PATCH 03/15] version --- build.gradle | 4 ++-- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index ef349f9..34d013e 100644 --- a/build.gradle +++ b/build.gradle @@ -73,8 +73,8 @@ subprojects { } publications { maven(MavenPublication) { - groupId = "com.zigythebird" - artifactId = "mochafloats-${project.name}" + groupId = "com.zigythebird.mochafloats" + artifactId = project.name version = project.version from components.java } diff --git a/gradle.properties b/gradle.properties index cd68e05..1c7d8b0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ group=team.unnamed -version=5.0.0 +version=6.0.0 description=A lightweight, fast and efficient Molang lexer, parser, interpreter and compiler for Java 24+ kotlin.stdlib.default.dependency=false \ No newline at end of file From c75021f93dda1f0d193f1e46ece87ccbbbe511a7 Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sun, 10 May 2026 00:49:15 +0700 Subject: [PATCH 04/15] Update build.gradle --- parser/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser/build.gradle b/parser/build.gradle index 703ec02..49d961e 100644 --- a/parser/build.gradle +++ b/parser/build.gradle @@ -1,4 +1,4 @@ dependencies { api project(":lexer") - api "io.netty:netty-buffer:4.2.12.Final" + api "io.netty:netty-buffer:4.2.13.Final" } From d1d6bf73be86b224ab978b535cf5b2d17a1bf1b8 Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sun, 10 May 2026 01:13:41 +0700 Subject: [PATCH 05/15] j2objc annotations --- build.gradle | 44 +------------------ .../unnamed/mocha/lexer/package-info.java | 5 ++- .../mocha/parser/ast/package-info.java | 5 ++- .../unnamed/mocha/parser/package-info.java | 5 ++- .../mocha/util/network/package-info.java | 4 ++ .../team/unnamed/mocha/util/package-info.java | 4 ++ .../java/team/unnamed/mocha/package-info.java | 4 ++ .../unnamed/mocha/runtime/MochaFunction.java | 2 + .../mocha/runtime/compiled/package-info.java | 4 ++ .../unnamed/mocha/runtime/package-info.java | 4 ++ .../team/unnamed/mocha/util/package-info.java | 4 ++ .../mocha/runtime/binding/package-info.java | 4 ++ .../unnamed/mocha/runtime/package-info.java | 4 ++ .../mocha/runtime/standard/package-info.java | 4 ++ .../mocha/runtime/value/package-info.java | 4 ++ .../team/unnamed/mocha/util/package-info.java | 4 ++ 16 files changed, 59 insertions(+), 46 deletions(-) create mode 100644 parser/src/main/java/team/unnamed/mocha/util/network/package-info.java create mode 100644 parser/src/main/java/team/unnamed/mocha/util/package-info.java create mode 100644 runtime-compiler/src/main/java/team/unnamed/mocha/package-info.java create mode 100644 runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java create mode 100644 runtime-compiler/src/main/java/team/unnamed/mocha/runtime/package-info.java create mode 100644 runtime-compiler/src/main/java/team/unnamed/mocha/util/package-info.java create mode 100644 runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java create mode 100644 runtime/src/main/java/team/unnamed/mocha/runtime/package-info.java create mode 100644 runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java create mode 100644 runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java create mode 100644 runtime/src/main/java/team/unnamed/mocha/util/package-info.java diff --git a/build.gradle b/build.gradle index 34d013e..86f0552 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,7 @@ subprojects { dependencies { compileOnlyApi("org.jetbrains:annotations:26.1.0") + compileOnlyApi("com.google.j2objc:j2objc-annotations:3.1") testImplementation("org.junit.jupiter:junit-jupiter-api:6.0.3") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:6.0.3") @@ -98,47 +99,4 @@ tasks { sourceCompatibility = "24" targetCompatibility = "24" } - compileJava { - sourceCompatibility = "24" - targetCompatibility = "24" - } - javadoc { - failOnError = false - } } - -license { - header.set(rootProject.resources.text.fromFile("header.txt")) - include("**/*.java") - newLine = false -} - -java { - withJavadocJar() - withSourcesJar() -} - -jar { - manifest.attributes("FMLModType": "GAMELIBRARY") -} - -publishing { - repositories { - maven { - name = "RedlanceMinecraft" - url = "https://repo.redlance.org/public" - credentials { - username = "dima_dencep" - password = System.getenv("MAVEN_PASSWORD") - } - } - } - publications { - maven(MavenPublication) { - groupId = "com.zigythebird" - artifactId = "mochafloats" - version = project.version - from components.java - } - } -} \ No newline at end of file diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java b/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java index b59988d..530b88d 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java +++ b/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java @@ -31,4 +31,7 @@ * * @since 3.0.0 */ -package team.unnamed.mocha.lexer; \ No newline at end of file +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.lexer; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java index fc81e5e..7ac31dd 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java @@ -33,4 +33,7 @@ * * @since 3.0.0 */ -package team.unnamed.mocha.parser.ast; \ No newline at end of file +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.parser.ast; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/parser/package-info.java b/parser/src/main/java/team/unnamed/mocha/parser/package-info.java index cde79f2..c30ae78 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/package-info.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/package-info.java @@ -30,4 +30,7 @@ * * @since 3.0.0 */ -package team.unnamed.mocha.parser; \ No newline at end of file +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.parser; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/util/network/package-info.java b/parser/src/main/java/team/unnamed/mocha/util/network/package-info.java new file mode 100644 index 0000000..4da0216 --- /dev/null +++ b/parser/src/main/java/team/unnamed/mocha/util/network/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.util.network; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/util/package-info.java b/parser/src/main/java/team/unnamed/mocha/util/package-info.java new file mode 100644 index 0000000..51b43be --- /dev/null +++ b/parser/src/main/java/team/unnamed/mocha/util/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.util; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/package-info.java b/runtime-compiler/src/main/java/team/unnamed/mocha/package-info.java new file mode 100644 index 0000000..d72ac74 --- /dev/null +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java index 2831a17..a495f13 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java @@ -23,6 +23,7 @@ */ package team.unnamed.mocha.runtime; +import com.google.j2objc.annotations.ReflectionSupport; import org.jetbrains.annotations.NotNull; import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; @@ -32,6 +33,7 @@ * @since 3.0.0 */ @FunctionalInterface +@ReflectionSupport(ReflectionSupport.Level.FULL) public interface MochaFunction extends MochaCompiledFunction { static @NotNull MochaFunction nop() { return NopMochaFunctionHolder.NOP; diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java new file mode 100644 index 0000000..285975d --- /dev/null +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.FULL) +package team.unnamed.mocha.runtime.compiled; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/package-info.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/package-info.java new file mode 100644 index 0000000..d6592f6 --- /dev/null +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.runtime; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/util/package-info.java b/runtime-compiler/src/main/java/team/unnamed/mocha/util/package-info.java new file mode 100644 index 0000000..51b43be --- /dev/null +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/util/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.util; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java new file mode 100644 index 0000000..409e8c9 --- /dev/null +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.FULL) +package team.unnamed.mocha.runtime.binding; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/package-info.java b/runtime/src/main/java/team/unnamed/mocha/runtime/package-info.java new file mode 100644 index 0000000..d6592f6 --- /dev/null +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.runtime; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java b/runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java new file mode 100644 index 0000000..f341450 --- /dev/null +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.FULL) +package team.unnamed.mocha.runtime.standard; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java new file mode 100644 index 0000000..666814c --- /dev/null +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.runtime.value; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/util/package-info.java b/runtime/src/main/java/team/unnamed/mocha/util/package-info.java new file mode 100644 index 0000000..51b43be --- /dev/null +++ b/runtime/src/main/java/team/unnamed/mocha/util/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.util; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file From 465af1fa394807205eddb64f53709c8daf5aee75 Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sun, 10 May 2026 01:59:59 +0700 Subject: [PATCH 06/15] Normalize line endings to LF Set `* text=auto eol=lf` in .gitattributes (with .bat as crlf and .jar as binary), align .editorconfig, and renormalize every tracked text file in one go. The repo previously had inconsistent EOLs within the same files (license header CRLF, body LF), which made every later edit show as a whole-file diff. Co-Authored-By: Claude Opus 4.7 (1M context) --- .editorconfig | 2 +- .gitattributes | 4 +- gradlew.bat | 164 +-- lexer/build.gradle | 2 +- .../team/unnamed/mocha/lexer/Characters.java | 48 +- .../java/team/unnamed/mocha/lexer/Cursor.java | 48 +- .../team/unnamed/mocha/lexer/MolangLexer.java | 48 +- .../unnamed/mocha/lexer/MolangLexerImpl.java | 48 +- .../java/team/unnamed/mocha/lexer/Token.java | 48 +- .../team/unnamed/mocha/lexer/TokenKind.java | 48 +- .../unnamed/mocha/lexer/package-info.java | 54 +- .../team/unnamed/mocha/lexer/LexerTest.java | 48 +- parser/build.gradle | 8 +- .../unnamed/mocha/parser/MolangParser.java | 48 +- .../mocha/parser/MolangParserImpl.java | 48 +- .../unnamed/mocha/parser/ParseException.java | 48 +- .../mocha/parser/ast/AccessExpression.java | 48 +- .../parser/ast/ArrayAccessExpression.java | 48 +- .../mocha/parser/ast/CallExpression.java | 238 +-- .../parser/ast/ExecutionScopeExpression.java | 182 +-- .../unnamed/mocha/parser/ast/Expression.java | 48 +- .../mocha/parser/ast/ExpressionVisitor.java | 354 ++--- .../parser/ast/IdentifierExpression.java | 48 +- .../mocha/parser/ast/StatementExpression.java | 48 +- .../mocha/parser/ast/StringExpression.java | 178 +-- .../ast/TernaryConditionalExpression.java | 316 ++-- .../mocha/parser/ast/UnaryExpression.java | 276 ++-- .../mocha/parser/ast/package-info.java | 54 +- .../unnamed/mocha/parser/package-info.java | 70 +- .../mocha/util/network/package-info.java | 6 +- .../mocha/parser/ArrayAccessParseTest.java | 48 +- .../unnamed/mocha/parser/CallParseTest.java | 48 +- .../unnamed/mocha/parser/DoubleParseTest.java | 48 +- .../mocha/parser/ParserAssertions.java | 216 +-- .../mocha/parser/TernaryParseTest.java | 48 +- runtime-compiler/build.gradle | 48 +- .../unnamed/mocha/runtime/MochaFunction.java | 48 +- .../unnamed/mocha/runtime/MolangCompiler.java | 750 +++++----- .../mocha/runtime/MolangCompilingVisitor.java | 1300 ++++++++--------- .../compiled/MochaCompiledFunction.java | 48 +- .../unnamed/mocha/runtime/compiled/Named.java | 48 +- .../mocha/runtime/compiled/package-info.java | 6 +- .../team/unnamed/mocha/MochaAssertions.java | 112 +- .../mocha/runtime/BreakContinueTest.java | 118 +- .../unnamed/mocha/runtime/CompareTest.java | 236 +-- .../mocha/runtime/ConstantValuesTest.java | 48 +- .../unnamed/mocha/runtime/FibonacciTest.java | 48 +- .../unnamed/mocha/runtime/ForEachTest.java | 48 +- .../runtime/InstanceMethodBindingTest.java | 48 +- .../unnamed/mocha/runtime/ParseErrorTest.java | 48 +- .../runtime/arrow/ArrowOperatorTest.java | 184 +-- .../unnamed/mocha/runtime/arrow/Player.java | 48 +- .../unnamed/mocha/runtime/arrow/World.java | 48 +- .../jvm/LogicalCompiledRuntimeTest.java | 48 +- .../runtime/jvm/MathCompiledRuntimeTest.java | 128 +- runtime/build.gradle | 6 +- .../mocha/runtime/ExecutionContext.java | 48 +- .../mocha/runtime/ExpressionInliner.java | 48 +- .../mocha/runtime/ExpressionInterpreter.java | 956 ++++++------ .../mocha/runtime/IsConstantExpression.java | 48 +- .../team/unnamed/mocha/runtime/JavaTypes.java | 48 +- .../mocha/runtime/MolangInterpreter.java | 788 +++++----- .../team/unnamed/mocha/runtime/Scope.java | 48 +- .../team/unnamed/mocha/runtime/ScopeImpl.java | 48 +- .../mocha/runtime/TypeCastException.java | 48 +- .../runtime/binding/BindExternalFunction.java | 48 +- .../mocha/runtime/binding/Binding.java | 48 +- .../unnamed/mocha/runtime/binding/Entity.java | 48 +- .../runtime/binding/JavaFieldBinding.java | 48 +- .../mocha/runtime/binding/JavaFunction.java | 48 +- .../runtime/binding/JavaObjectBinding.java | 48 +- .../unnamed/mocha/runtime/binding/Lazy.java | 48 +- .../runtime/binding/ReflectiveFunction.java | 48 +- .../runtime/binding/RegisteredBinding.java | 48 +- .../mocha/runtime/binding/package-info.java | 6 +- .../mocha/runtime/standard/package-info.java | 6 +- .../mocha/runtime/value/ArrayValue.java | 48 +- .../unnamed/mocha/runtime/value/Function.java | 48 +- .../mocha/runtime/value/JavaValue.java | 48 +- .../runtime/value/MutableObjectBinding.java | 48 +- .../mocha/runtime/value/NumberValue.java | 172 +-- .../mocha/runtime/value/ObjectProperty.java | 48 +- .../runtime/value/ObjectPropertyImpl.java | 48 +- .../mocha/runtime/value/ObjectValue.java | 202 +-- .../mocha/runtime/value/StringValue.java | 48 +- .../unnamed/mocha/runtime/value/Value.java | 48 +- .../mocha/runtime/value/package-info.java | 6 +- .../util/CaseInsensitiveStringHashMap.java | 48 +- .../mocha/runtime/value/ValueOfTest.java | 98 +- .../CaseInsensitiveStringHashMapTest.java | 48 +- .../team/unnamed/mocha/CompareBenchmark.java | 48 +- 91 files changed, 4992 insertions(+), 4990 deletions(-) diff --git a/.editorconfig b/.editorconfig index c088a82..aa0df99 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,7 +2,7 @@ root = true [*] charset = utf-8 -end_of_line = crlf +end_of_line = lf insert_final_newline = false indent_size = 4 indent_style = space diff --git a/.gitattributes b/.gitattributes index 5378fe0..0161913 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,3 @@ -* -text \ No newline at end of file +* text=auto eol=lf +*.bat text eol=crlf +*.jar binary \ No newline at end of file diff --git a/gradlew.bat b/gradlew.bat index aa5f10b..24c62d5 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,82 +1,82 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables, and ensure extensions are enabled -setlocal EnableExtensions - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -"%COMSPEC%" /c exit 1 - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -"%COMSPEC%" /c exit 1 - -:execute -@rem Setup the command line - - - -@rem Execute Gradle -@rem endlocal doesn't take effect until after the line is parsed and variables are expanded -@rem which allows us to clear the local environment before executing the java command -endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel - -:exitWithErrorLevel -@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts -"%COMSPEC%" /c exit %ERRORLEVEL% +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +"%COMSPEC%" /c exit 1 + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +"%COMSPEC%" /c exit 1 + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel + +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/lexer/build.gradle b/lexer/build.gradle index 2fbc1d4..87806a2 100644 --- a/lexer/build.gradle +++ b/lexer/build.gradle @@ -1 +1 @@ -// no internal dependencies +// no internal dependencies diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/Characters.java b/lexer/src/main/java/team/unnamed/mocha/lexer/Characters.java index d7cff56..57981ce 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/Characters.java +++ b/lexer/src/main/java/team/unnamed/mocha/lexer/Characters.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.lexer; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.lexer; import org.jetbrains.annotations.ApiStatus; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/Cursor.java b/lexer/src/main/java/team/unnamed/mocha/lexer/Cursor.java index 2b6948e..6b32078 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/Cursor.java +++ b/lexer/src/main/java/team/unnamed/mocha/lexer/Cursor.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.lexer; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.lexer; import org.jetbrains.annotations.NotNull; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexer.java b/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexer.java index c9dc0d3..1025c0f 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexer.java +++ b/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexer.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.lexer; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.lexer; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java b/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java index c974a46..83b1765 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java +++ b/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.lexer; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.lexer; import org.jetbrains.annotations.NotNull; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/Token.java b/lexer/src/main/java/team/unnamed/mocha/lexer/Token.java index a1153d1..5d4ac9d 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/Token.java +++ b/lexer/src/main/java/team/unnamed/mocha/lexer/Token.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.lexer; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.lexer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/TokenKind.java b/lexer/src/main/java/team/unnamed/mocha/lexer/TokenKind.java index 9e5c3cf..79fd8fb 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/TokenKind.java +++ b/lexer/src/main/java/team/unnamed/mocha/lexer/TokenKind.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.lexer; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.lexer; import org.jetbrains.annotations.NotNull; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java b/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java index 530b88d..c83c258 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java +++ b/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -/** +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +/** * Package containing classes related to lexicographical * analysis of Molang code. * @@ -31,7 +31,7 @@ * * @since 3.0.0 */ -@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.lexer; - +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.lexer; + import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/lexer/src/test/java/team/unnamed/mocha/lexer/LexerTest.java b/lexer/src/test/java/team/unnamed/mocha/lexer/LexerTest.java index f115409..13f08f1 100644 --- a/lexer/src/test/java/team/unnamed/mocha/lexer/LexerTest.java +++ b/lexer/src/test/java/team/unnamed/mocha/lexer/LexerTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.lexer; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.lexer; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/parser/build.gradle b/parser/build.gradle index 49d961e..59f8a14 100644 --- a/parser/build.gradle +++ b/parser/build.gradle @@ -1,4 +1,4 @@ -dependencies { - api project(":lexer") - api "io.netty:netty-buffer:4.2.13.Final" -} +dependencies { + api project(":lexer") + api "io.netty:netty-buffer:4.2.13.Final" +} diff --git a/parser/src/main/java/team/unnamed/mocha/parser/MolangParser.java b/parser/src/main/java/team/unnamed/mocha/parser/MolangParser.java index 81f1108..f88ae91 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/MolangParser.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/MolangParser.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java b/parser/src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java index 495d31f..6e5f28e 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ParseException.java b/parser/src/main/java/team/unnamed/mocha/parser/ParseException.java index 0f80ca7..4c33ade 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ParseException.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ParseException.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser; import org.jetbrains.annotations.Nullable; import team.unnamed.mocha.lexer.Cursor; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java index fcc63b1..ce83087 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java index b671396..aba9a2f 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java index c857c6e..1ecb4a5 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java @@ -1,120 +1,120 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; - -import io.netty.buffer.ByteBuf; -import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; -import team.unnamed.mocha.util.ExpressionListUtils; - -import java.util.List; - -import static java.util.Objects.requireNonNull; - -/** - * Call expression implementation, executes functions - * with certain arguments. - * - *

Example call expressions: {@code print('hello')}, - * {@code math.sqrt(9)}, {@code math.pow(3, 2)}

- * - * @since 3.0.0 - */ -public final class CallExpression implements Expression { - private final List arguments; - private Expression function; - - public CallExpression(ByteBuf buf) { - this( - ExprBytesUtils.readExpression(buf), - ExprBytesUtils.readExpressions(buf) - ); - } - - public CallExpression(final @NotNull Expression function, final @NotNull List arguments) { - this.function = requireNonNull(function, "function"); - this.arguments = requireNonNull(arguments, "arguments"); - } - - /** - * Gets the function expression. - * - * @since 3.0.0 - */ - public @NotNull Expression function() { - return function; - } - - /** - * Sets the function expression. - * - * @since 3.0.0 - */ - public void function(final @NotNull Expression function) { - this.function = requireNonNull(function, "function"); - } - - /** - * Gets the list of arguments to pass to - * the function. - * - * @since 3.0.0 - */ - public @NotNull List arguments() { - return arguments; - } - - @Override - public R visit(final @NotNull ExpressionVisitor visitor) { - return visitor.visitCall(this); - } - - @Override - public void write(ByteBuf buf) { - ExprBytesUtils.writeExpression(function(), buf); - ExprBytesUtils.writeExpressions(arguments(), buf); - } - - @Override - public String toString() { - return String.format("%s(%s)", function, ExpressionListUtils.toString(this.arguments, ",")); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - CallExpression that = (CallExpression) o; - if (!function.equals(that.function)) return false; - return arguments.equals(that.arguments); - } - - @Override - public int hashCode() { - int result = function.hashCode(); - result = 31 * result + arguments.hashCode(); - return result; - } - +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; + +import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; +import team.unnamed.mocha.util.ExprBytesUtils; +import team.unnamed.mocha.util.ExpressionListUtils; + +import java.util.List; + +import static java.util.Objects.requireNonNull; + +/** + * Call expression implementation, executes functions + * with certain arguments. + * + *

Example call expressions: {@code print('hello')}, + * {@code math.sqrt(9)}, {@code math.pow(3, 2)}

+ * + * @since 3.0.0 + */ +public final class CallExpression implements Expression { + private final List arguments; + private Expression function; + + public CallExpression(ByteBuf buf) { + this( + ExprBytesUtils.readExpression(buf), + ExprBytesUtils.readExpressions(buf) + ); + } + + public CallExpression(final @NotNull Expression function, final @NotNull List arguments) { + this.function = requireNonNull(function, "function"); + this.arguments = requireNonNull(arguments, "arguments"); + } + + /** + * Gets the function expression. + * + * @since 3.0.0 + */ + public @NotNull Expression function() { + return function; + } + + /** + * Sets the function expression. + * + * @since 3.0.0 + */ + public void function(final @NotNull Expression function) { + this.function = requireNonNull(function, "function"); + } + + /** + * Gets the list of arguments to pass to + * the function. + * + * @since 3.0.0 + */ + public @NotNull List arguments() { + return arguments; + } + + @Override + public R visit(final @NotNull ExpressionVisitor visitor) { + return visitor.visitCall(this); + } + + @Override + public void write(ByteBuf buf) { + ExprBytesUtils.writeExpression(function(), buf); + ExprBytesUtils.writeExpressions(arguments(), buf); + } + + @Override + public String toString() { + return String.format("%s(%s)", function, ExpressionListUtils.toString(this.arguments, ",")); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CallExpression that = (CallExpression) o; + if (!function.equals(that.function)) return false; + return arguments.equals(that.arguments); + } + + @Override + public int hashCode() { + int result = function.hashCode(); + result = 31 * result + arguments.hashCode(); + return result; + } + } \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java index 14510eb..33dcb68 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java @@ -1,92 +1,92 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; - -import io.netty.buffer.ByteBuf; -import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; -import team.unnamed.mocha.util.ExpressionListUtils; - -import java.util.List; -import java.util.Objects; - -/** - * Execution scope expression implementation. Execution - * scopes define a new scope and a new sequence of - * expressions to evaluate. - * - *

Execution scope expression examples: {@code { print('a'); print('b'); }}, - * {@code { doThisFirst(); thenDoThis(); }}, {@code { v.x = v.x + 1; }}

- * - * @since 3.0.0 - */ -public final class ExecutionScopeExpression implements Expression { - - private final List expressions; - - public ExecutionScopeExpression(ByteBuf buf) { - this(ExprBytesUtils.readExpressions(buf)); - } - - public ExecutionScopeExpression(final @NotNull List expressions) { - this.expressions = Objects.requireNonNull(expressions, "expressions"); - } - - /** - * Returns the expressions inside this - * execution scope, never null - */ - public @NotNull List expressions() { - return expressions; - } - - @Override - public R visit(final @NotNull ExpressionVisitor visitor) { - return visitor.visitExecutionScope(this); - } - - @Override - public void write(ByteBuf buf) { - ExprBytesUtils.writeExpressions(expressions(), buf); - } - - @Override - public String toString() { - return String.format("{%s}", ExpressionListUtils.toString(this.expressions)); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ExecutionScopeExpression that = (ExecutionScopeExpression) o; - return expressions.equals(that.expressions); - } - - @Override - public int hashCode() { - return Objects.hash(expressions); - } - +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; + +import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; +import team.unnamed.mocha.util.ExprBytesUtils; +import team.unnamed.mocha.util.ExpressionListUtils; + +import java.util.List; +import java.util.Objects; + +/** + * Execution scope expression implementation. Execution + * scopes define a new scope and a new sequence of + * expressions to evaluate. + * + *

Execution scope expression examples: {@code { print('a'); print('b'); }}, + * {@code { doThisFirst(); thenDoThis(); }}, {@code { v.x = v.x + 1; }}

+ * + * @since 3.0.0 + */ +public final class ExecutionScopeExpression implements Expression { + + private final List expressions; + + public ExecutionScopeExpression(ByteBuf buf) { + this(ExprBytesUtils.readExpressions(buf)); + } + + public ExecutionScopeExpression(final @NotNull List expressions) { + this.expressions = Objects.requireNonNull(expressions, "expressions"); + } + + /** + * Returns the expressions inside this + * execution scope, never null + */ + public @NotNull List expressions() { + return expressions; + } + + @Override + public R visit(final @NotNull ExpressionVisitor visitor) { + return visitor.visitExecutionScope(this); + } + + @Override + public void write(ByteBuf buf) { + ExprBytesUtils.writeExpressions(expressions(), buf); + } + + @Override + public String toString() { + return String.format("{%s}", ExpressionListUtils.toString(this.expressions)); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ExecutionScopeExpression that = (ExecutionScopeExpression) o; + return expressions.equals(that.expressions); + } + + @Override + public int hashCode() { + return Objects.hash(expressions); + } + } \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/Expression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/Expression.java index 981b857..75a29b4 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/Expression.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/Expression.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.ApiStatus; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java index 39710db..d5f04bf 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java @@ -1,178 +1,178 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; - -import org.jetbrains.annotations.NotNull; - -/** - * An {@link Expression} visitor. Provides a way to add - * functionalities to the expression interface and all - * of its implementations. - * - *

See the following example on visiting an expression:

- *
{@code
- *      Expression expr = ...;
- *      String str = expr.visit(new ToStringVisitor());
- * }
- * - *

Please note that users MUST use {@link Expression#visit(ExpressionVisitor)} - * and NOT ExpressionVisitor's {@link ExpressionVisitor#visit(Expression)}, because - * it will not work as intended.

- * - * @param The visit result type - * @since 3.0.0 - */ -public interface ExpressionVisitor { - - /** - * Evaluate for the given unknown expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - R visit(final @NotNull Expression expression); - - /** - * Evaluate for array access expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitArrayAccess(final @NotNull ArrayAccessExpression expression) { - return visit(expression); - } - - /** - * Evaluate for float expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitFloat(final @NotNull FloatExpression expression) { - return visit(expression); - } - - /** - * Evaluate for string expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitString(final @NotNull StringExpression expression) { - return visit(expression); - } - - /** - * Evaluate for identifier expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitIdentifier(final @NotNull IdentifierExpression expression) { - return visit(expression); - } - - /** - * Evaluate for ternary conditional expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitTernaryConditional(final @NotNull TernaryConditionalExpression expression) { - return visit(expression); - } - - /** - * Evaluate for unary expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitUnary(final @NotNull UnaryExpression expression) { - return visit(expression); - } - - /** - * Evaluate for execution scope expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitExecutionScope(final @NotNull ExecutionScopeExpression expression) { - return visit(expression); - } - - /** - * Evaluate for binary expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitBinary(final @NotNull BinaryExpression expression) { - return visit(expression); - } - - /** - * Evaluate for access expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitAccess(final @NotNull AccessExpression expression) { - return visit(expression); - } - - /** - * Evaluate for call expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitCall(final @NotNull CallExpression expression) { - return visit(expression); - } - - /** - * Evaluate for statement expression. - * - * @param expression The expression. - * @return The result. - * @since 3.0.0 - */ - default R visitStatement(final @NotNull StatementExpression expression) { - return visit(expression); - } - +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * An {@link Expression} visitor. Provides a way to add + * functionalities to the expression interface and all + * of its implementations. + * + *

See the following example on visiting an expression:

+ *
{@code
+ *      Expression expr = ...;
+ *      String str = expr.visit(new ToStringVisitor());
+ * }
+ * + *

Please note that users MUST use {@link Expression#visit(ExpressionVisitor)} + * and NOT ExpressionVisitor's {@link ExpressionVisitor#visit(Expression)}, because + * it will not work as intended.

+ * + * @param The visit result type + * @since 3.0.0 + */ +public interface ExpressionVisitor { + + /** + * Evaluate for the given unknown expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + R visit(final @NotNull Expression expression); + + /** + * Evaluate for array access expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitArrayAccess(final @NotNull ArrayAccessExpression expression) { + return visit(expression); + } + + /** + * Evaluate for float expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitFloat(final @NotNull FloatExpression expression) { + return visit(expression); + } + + /** + * Evaluate for string expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitString(final @NotNull StringExpression expression) { + return visit(expression); + } + + /** + * Evaluate for identifier expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitIdentifier(final @NotNull IdentifierExpression expression) { + return visit(expression); + } + + /** + * Evaluate for ternary conditional expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitTernaryConditional(final @NotNull TernaryConditionalExpression expression) { + return visit(expression); + } + + /** + * Evaluate for unary expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitUnary(final @NotNull UnaryExpression expression) { + return visit(expression); + } + + /** + * Evaluate for execution scope expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitExecutionScope(final @NotNull ExecutionScopeExpression expression) { + return visit(expression); + } + + /** + * Evaluate for binary expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitBinary(final @NotNull BinaryExpression expression) { + return visit(expression); + } + + /** + * Evaluate for access expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitAccess(final @NotNull AccessExpression expression) { + return visit(expression); + } + + /** + * Evaluate for call expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitCall(final @NotNull CallExpression expression) { + return visit(expression); + } + + /** + * Evaluate for statement expression. + * + * @param expression The expression. + * @return The result. + * @since 3.0.0 + */ + default R visitStatement(final @NotNull StatementExpression expression) { + return visit(expression); + } + } \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java index 4056a81..fcacde6 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java index 0c68804..e1ebcbf 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java index 42e8152..2eea978 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java @@ -1,90 +1,90 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; - -import io.netty.buffer.ByteBuf; -import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.network.ProtocolUtils; - -import java.util.Objects; - -/** - * String literal expression implementation for Molang. - * - *

Example string expressions: {@code 'hello world'}, - * {@code 'hey there'}, {@code 'name'}, {@code 'the game'}

- * - * @since 3.0.0 - */ -public final class StringExpression implements Expression { - - private final String value; - - public StringExpression(ByteBuf buf) { - this(ProtocolUtils.readString(buf)); - } - - public StringExpression(final @NotNull String value) { - this.value = Objects.requireNonNull(value, "value"); - } - - /** - * Gets the string value for this expression. - * - * @return The string value. - * @since 3.0.0 - */ - public @NotNull String value() { - return value; - } - - @Override - public R visit(final @NotNull ExpressionVisitor visitor) { - return visitor.visitString(this); - } - - @Override - public void write(ByteBuf buf) { - ProtocolUtils.writeString(buf, value()); - } - - @Override - public String toString() { - return String.format("'%s'", value); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - StringExpression that = (StringExpression) o; - return value.equals(that.value); - } - - @Override - public int hashCode() { - return value.hashCode(); - } - +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; + +import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; +import team.unnamed.mocha.util.network.ProtocolUtils; + +import java.util.Objects; + +/** + * String literal expression implementation for Molang. + * + *

Example string expressions: {@code 'hello world'}, + * {@code 'hey there'}, {@code 'name'}, {@code 'the game'}

+ * + * @since 3.0.0 + */ +public final class StringExpression implements Expression { + + private final String value; + + public StringExpression(ByteBuf buf) { + this(ProtocolUtils.readString(buf)); + } + + public StringExpression(final @NotNull String value) { + this.value = Objects.requireNonNull(value, "value"); + } + + /** + * Gets the string value for this expression. + * + * @return The string value. + * @since 3.0.0 + */ + public @NotNull String value() { + return value; + } + + @Override + public R visit(final @NotNull ExpressionVisitor visitor) { + return visitor.visitString(this); + } + + @Override + public void write(ByteBuf buf) { + ProtocolUtils.writeString(buf, value()); + } + + @Override + public String toString() { + return String.format("'%s'", value); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + StringExpression that = (StringExpression) o; + return value.equals(that.value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + } \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java index ab0033d..c6ca884 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java @@ -1,159 +1,159 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; - -import io.netty.buffer.ByteBuf; -import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; - -import java.util.Objects; - -import static java.util.Objects.requireNonNull; - -/** - * Ternary conditional expression implementation, similar to - * "if {...} else {...}" expressions in other languages. - * - *

If the {@code conditional} expression evaluates to a - * truthy value, then {@code trueExpression} is evaluated - * as the result, otherwise, {@code falseExpression} is.

- * - *

Example ternary conditional expressions: {@code true ? 1 : 0}, - * {@code (age > 18) ? 'adult' : 'minor'}, {@code open ? 'open' : 'closed'}

- * - * @since 3.0.0 - */ -public final class TernaryConditionalExpression implements Expression { - private Expression conditional; - private Expression trueExpression; - private Expression falseExpression; - - public TernaryConditionalExpression(ByteBuf buf) { - this( - ExprBytesUtils.readExpression(buf), - ExprBytesUtils.readExpression(buf), - ExprBytesUtils.readExpression(buf) - ); - } - - public TernaryConditionalExpression(final @NotNull Expression conditional, final @NotNull Expression trueExpression, final @NotNull Expression falseExpression) { - this.conditional = requireNonNull(conditional, "conditional"); - this.trueExpression = requireNonNull(trueExpression, "trueExpression"); - this.falseExpression = requireNonNull(falseExpression, "falseExpression"); - } - - /** - * Gets the expression condition. - * - * @since 3.0.0 - */ - public @NotNull Expression condition() { - return conditional; - } - - /** - * Sets the expression condition. - * - * @param condition The condition - * @since 3.0.0 - */ - public void condition(final @NotNull Expression condition) { - this.conditional = requireNonNull(condition, "condition"); - } - - /** - * Gets the expression that should be used when - * condition is evaluated as a truthy value. - * - * @since 3.0.0 - */ - public @NotNull Expression trueExpression() { - return trueExpression; - } - - /** - * Sets the expression that should be used when - * condition is evaluated as a truthy value. - * - * @param trueExpression The true expression - * @since 3.0.0 - */ - public void trueExpression(final @NotNull Expression trueExpression) { - this.trueExpression = requireNonNull(trueExpression, "trueExpression"); - } - - /** - * Gets the expression that should be used when - * condition is evaluated as a falsy value. - * - * @since 3.0.0 - */ - public @NotNull Expression falseExpression() { - return falseExpression; - } - - /** - * Sets the expression that should be used when - * condition is evaluated as a falsy value. - * - * @param falseExpression The false expression - * @since 3.0.0 - */ - public void falseExpression(final @NotNull Expression falseExpression) { - this.falseExpression = requireNonNull(falseExpression, "falseExpression"); - } - - @Override - public R visit(final @NotNull ExpressionVisitor visitor) { - return visitor.visitTernaryConditional(this); - } - - @Override - public void write(ByteBuf buf) { - ExprBytesUtils.writeExpression(conditional, buf); - ExprBytesUtils.writeExpression(trueExpression, buf); - ExprBytesUtils.writeExpression(falseExpression, buf); - } - - @Override - public String toString() { - return String.format("(%s)?%s:%s", conditional, trueExpression, falseExpression); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - TernaryConditionalExpression that = (TernaryConditionalExpression) o; - return conditional.equals(that.conditional) - && trueExpression.equals(that.trueExpression) - && falseExpression.equals(that.falseExpression); - } - - @Override - public int hashCode() { - return Objects.hash(conditional, trueExpression, falseExpression); - } - +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; + +import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; +import team.unnamed.mocha.util.ExprBytesUtils; + +import java.util.Objects; + +import static java.util.Objects.requireNonNull; + +/** + * Ternary conditional expression implementation, similar to + * "if {...} else {...}" expressions in other languages. + * + *

If the {@code conditional} expression evaluates to a + * truthy value, then {@code trueExpression} is evaluated + * as the result, otherwise, {@code falseExpression} is.

+ * + *

Example ternary conditional expressions: {@code true ? 1 : 0}, + * {@code (age > 18) ? 'adult' : 'minor'}, {@code open ? 'open' : 'closed'}

+ * + * @since 3.0.0 + */ +public final class TernaryConditionalExpression implements Expression { + private Expression conditional; + private Expression trueExpression; + private Expression falseExpression; + + public TernaryConditionalExpression(ByteBuf buf) { + this( + ExprBytesUtils.readExpression(buf), + ExprBytesUtils.readExpression(buf), + ExprBytesUtils.readExpression(buf) + ); + } + + public TernaryConditionalExpression(final @NotNull Expression conditional, final @NotNull Expression trueExpression, final @NotNull Expression falseExpression) { + this.conditional = requireNonNull(conditional, "conditional"); + this.trueExpression = requireNonNull(trueExpression, "trueExpression"); + this.falseExpression = requireNonNull(falseExpression, "falseExpression"); + } + + /** + * Gets the expression condition. + * + * @since 3.0.0 + */ + public @NotNull Expression condition() { + return conditional; + } + + /** + * Sets the expression condition. + * + * @param condition The condition + * @since 3.0.0 + */ + public void condition(final @NotNull Expression condition) { + this.conditional = requireNonNull(condition, "condition"); + } + + /** + * Gets the expression that should be used when + * condition is evaluated as a truthy value. + * + * @since 3.0.0 + */ + public @NotNull Expression trueExpression() { + return trueExpression; + } + + /** + * Sets the expression that should be used when + * condition is evaluated as a truthy value. + * + * @param trueExpression The true expression + * @since 3.0.0 + */ + public void trueExpression(final @NotNull Expression trueExpression) { + this.trueExpression = requireNonNull(trueExpression, "trueExpression"); + } + + /** + * Gets the expression that should be used when + * condition is evaluated as a falsy value. + * + * @since 3.0.0 + */ + public @NotNull Expression falseExpression() { + return falseExpression; + } + + /** + * Sets the expression that should be used when + * condition is evaluated as a falsy value. + * + * @param falseExpression The false expression + * @since 3.0.0 + */ + public void falseExpression(final @NotNull Expression falseExpression) { + this.falseExpression = requireNonNull(falseExpression, "falseExpression"); + } + + @Override + public R visit(final @NotNull ExpressionVisitor visitor) { + return visitor.visitTernaryConditional(this); + } + + @Override + public void write(ByteBuf buf) { + ExprBytesUtils.writeExpression(conditional, buf); + ExprBytesUtils.writeExpression(trueExpression, buf); + ExprBytesUtils.writeExpression(falseExpression, buf); + } + + @Override + public String toString() { + return String.format("(%s)?%s:%s", conditional, trueExpression, falseExpression); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TernaryConditionalExpression that = (TernaryConditionalExpression) o; + return conditional.equals(that.conditional) + && trueExpression.equals(that.trueExpression) + && falseExpression.equals(that.falseExpression); + } + + @Override + public int hashCode() { + return Objects.hash(conditional, trueExpression, falseExpression); + } + } \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java index 732821e..3635424 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java @@ -1,138 +1,138 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser.ast; - -import io.netty.buffer.ByteBuf; -import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; -import team.unnamed.mocha.util.network.ProtocolUtils; - -import static java.util.Objects.requireNonNull; - -/** - * Unary expression implementation, performs a single operation - * to a single expression, like logical negation, arithmetical - * negation, or "return expr;". - * - *

Example unary expressions: {@code -hello}, {@code !p}, - * {@code !q}, {@code -(10 * 5)}, {@code return this}, - * {@code return 5}

- * - * @since 3.0.0 - */ -public final class UnaryExpression implements Expression { - private final Op op; - private Expression expression; - - public UnaryExpression(ByteBuf buf) { - this( - ProtocolUtils.readEnum(Op.class, buf), - ExprBytesUtils.readExpression(buf) - ); - } - - public UnaryExpression(final @NotNull Op op, final @NotNull Expression expression) { - this.op = requireNonNull(op, "op"); - this.expression = requireNonNull(expression, "expression"); - } - - /** - * Gets the unary expression operation. - * - * @return The unary expression operation. - * @since 3.0.0 - */ - public @NotNull Op op() { - return op; - } - - /** - * Gets the operated expression. - * - * @return The operated expression. - * @since 3.0.0 - */ - public @NotNull Expression expression() { - return expression; - } - - /** - * Sets the operated expression. - * - * @param expression The operated expression. - * @since 3.0.0 - */ - public void expression(final @NotNull Expression expression) { - this.expression = requireNonNull(expression, "expression"); - } - - @Override - public R visit(final @NotNull ExpressionVisitor visitor) { - return visitor.visitUnary(this); - } - - @Override - public void write(ByteBuf buf) { - ProtocolUtils.writeEnum(op(), buf); - ExprBytesUtils.writeExpression(this.expression, buf); - } - - @Override - public String toString() { - return String.format("%s(%s)", op, expression); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - UnaryExpression that = (UnaryExpression) o; - if (op != that.op) return false; - return expression.equals(that.expression); - } - - @Override - public int hashCode() { - int result = op.hashCode(); - result = 31 * result + expression.hashCode(); - return result; - } - - public enum Op { - LOGICAL_NEGATION("!"), - ARITHMETICAL_NEGATION("-"), - RETURN("return "); - - private final String string; - - Op(String string) { - this.string = string; - } - - @Override - public String toString() { - return this.string; - } - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser.ast; + +import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; +import team.unnamed.mocha.util.ExprBytesUtils; +import team.unnamed.mocha.util.network.ProtocolUtils; + +import static java.util.Objects.requireNonNull; + +/** + * Unary expression implementation, performs a single operation + * to a single expression, like logical negation, arithmetical + * negation, or "return expr;". + * + *

Example unary expressions: {@code -hello}, {@code !p}, + * {@code !q}, {@code -(10 * 5)}, {@code return this}, + * {@code return 5}

+ * + * @since 3.0.0 + */ +public final class UnaryExpression implements Expression { + private final Op op; + private Expression expression; + + public UnaryExpression(ByteBuf buf) { + this( + ProtocolUtils.readEnum(Op.class, buf), + ExprBytesUtils.readExpression(buf) + ); + } + + public UnaryExpression(final @NotNull Op op, final @NotNull Expression expression) { + this.op = requireNonNull(op, "op"); + this.expression = requireNonNull(expression, "expression"); + } + + /** + * Gets the unary expression operation. + * + * @return The unary expression operation. + * @since 3.0.0 + */ + public @NotNull Op op() { + return op; + } + + /** + * Gets the operated expression. + * + * @return The operated expression. + * @since 3.0.0 + */ + public @NotNull Expression expression() { + return expression; + } + + /** + * Sets the operated expression. + * + * @param expression The operated expression. + * @since 3.0.0 + */ + public void expression(final @NotNull Expression expression) { + this.expression = requireNonNull(expression, "expression"); + } + + @Override + public R visit(final @NotNull ExpressionVisitor visitor) { + return visitor.visitUnary(this); + } + + @Override + public void write(ByteBuf buf) { + ProtocolUtils.writeEnum(op(), buf); + ExprBytesUtils.writeExpression(this.expression, buf); + } + + @Override + public String toString() { + return String.format("%s(%s)", op, expression); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UnaryExpression that = (UnaryExpression) o; + if (op != that.op) return false; + return expression.equals(that.expression); + } + + @Override + public int hashCode() { + int result = op.hashCode(); + result = 31 * result + expression.hashCode(); + return result; + } + + public enum Op { + LOGICAL_NEGATION("!"), + ARITHMETICAL_NEGATION("-"), + RETURN("return "); + + private final String string; + + Op(String string) { + this.string = string; + } + + @Override + public String toString() { + return this.string; + } + } +} diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java b/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java index 7ac31dd..8215b65 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -/** +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +/** * Package containing classes for Molang abstract syntax trees. * *

Syntax trees are structures made out of expressions. Some @@ -33,7 +33,7 @@ * * @since 3.0.0 */ -@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.parser.ast; - +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.parser.ast; + import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/parser/package-info.java b/parser/src/main/java/team/unnamed/mocha/parser/package-info.java index c30ae78..841b6c5 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/package-info.java +++ b/parser/src/main/java/team/unnamed/mocha/parser/package-info.java @@ -1,36 +1,36 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -/** - * Package containing classes related to parsing of Molang code. - * - *

This means converting a stream of tokens to a stream of - * Molang expressions, e.g. (float plus float) -> (Add(float, float)), - * or (identifier dot identifier)) -> (Access(identifier, identifier))

- * - * @since 3.0.0 - */ -@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.parser; - +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +/** + * Package containing classes related to parsing of Molang code. + * + *

This means converting a stream of tokens to a stream of + * Molang expressions, e.g. (float plus float) -> (Add(float, float)), + * or (identifier dot identifier)) -> (Access(identifier, identifier))

+ * + * @since 3.0.0 + */ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.parser; + import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/util/network/package-info.java b/parser/src/main/java/team/unnamed/mocha/util/network/package-info.java index 4da0216..10b5e8c 100644 --- a/parser/src/main/java/team/unnamed/mocha/util/network/package-info.java +++ b/parser/src/main/java/team/unnamed/mocha/util/network/package-info.java @@ -1,4 +1,4 @@ -@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.util.network; - +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.util.network; + import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java b/parser/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java index 97b4b03..fa29e14 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser; import org.junit.jupiter.api.Test; import team.unnamed.mocha.parser.ast.*; diff --git a/parser/src/test/java/team/unnamed/mocha/parser/CallParseTest.java b/parser/src/test/java/team/unnamed/mocha/parser/CallParseTest.java index 69c9fa7..a566d08 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/CallParseTest.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/CallParseTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser; import org.junit.jupiter.api.Test; import team.unnamed.mocha.parser.ast.*; diff --git a/parser/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java b/parser/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java index 9e24116..19c0097 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser; import org.junit.jupiter.api.Test; import team.unnamed.mocha.parser.ast.FloatExpression; diff --git a/parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java b/parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java index 574fa8c..f137829 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java @@ -1,108 +1,108 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.util.ExprBytesUtils; - -import java.io.IOException; -import java.io.StringReader; -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - -public final class ParserAssertions { - private ParserAssertions() { - throw new UnsupportedOperationException("This class cannot be instantiated"); - } - - public static @NotNull List parse(final @NotNull String expr) throws ParseException { - try (final StringReader reader = new StringReader(expr)) { - return MolangParser.parser(reader).parseAll(); - } catch (final ParseException e) { - throw e; - } catch (final IOException e) { - throw new AssertionError("StringReader IOException", e); - } - } - - public static void assertCreateSameTree(final @NotNull String expr1, final @NotNull String expr2) throws ParseException { - final List expressions1 = parse(expr1); - final List expressions2 = parse(expr2); - assertEquals(expressions1, expressions2, () -> "Expressions:\n\t- " + - expr1 + - "\n\t- " + - expr2 + - "\nGenerated different syntax trees:\n\t- " + - expressions1 + - "\n\t- " + - expressions2); - } - - public static void assertCreateTree(final @NotNull String expr, final @NotNull Expression @NotNull ... expressions) { - assertCreateTree(expr, Arrays.asList(expressions)); - } - - public static void assertCreateTree(final @NotNull String expr, final List expressions) { - final List parsed; - try { - parsed = parse(expr); - } catch (final ParseException e) { - fail("Failed to parse expression: '" + expr + "'", e); - return; - } - - { // Network round-trip - ByteBuf buf = Unpooled.buffer(); - ExprBytesUtils.writeExpressions(expressions, buf); - - List readed = ExprBytesUtils.readExpressions(buf); - buf.release(); - - assertEquals(readed, expressions); - } - - assertEquals( - expressions, - parsed, - () -> "Expression: '" + expr + "' generated unexpected syntax tree:\n\t" + - "- Expected: " + expressions + "\n\t" + - "- Got: " + parsed - ); - } - - public static void assertParseError(final @NotNull String expr, final int column) { - try { - final List expressions = parse(expr); - fail("Expected parse error at column " + column + " for expression: '" + expr + "', instead, it was parsed as: " + expressions); - } catch (final ParseException e) { - assertEquals(column, e.cursor().column(), "Expected parse error at column " + column + " for expression: '" + expr + "'"); - } - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.jetbrains.annotations.NotNull; +import team.unnamed.mocha.parser.ast.Expression; +import team.unnamed.mocha.util.ExprBytesUtils; + +import java.io.IOException; +import java.io.StringReader; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +public final class ParserAssertions { + private ParserAssertions() { + throw new UnsupportedOperationException("This class cannot be instantiated"); + } + + public static @NotNull List parse(final @NotNull String expr) throws ParseException { + try (final StringReader reader = new StringReader(expr)) { + return MolangParser.parser(reader).parseAll(); + } catch (final ParseException e) { + throw e; + } catch (final IOException e) { + throw new AssertionError("StringReader IOException", e); + } + } + + public static void assertCreateSameTree(final @NotNull String expr1, final @NotNull String expr2) throws ParseException { + final List expressions1 = parse(expr1); + final List expressions2 = parse(expr2); + assertEquals(expressions1, expressions2, () -> "Expressions:\n\t- " + + expr1 + + "\n\t- " + + expr2 + + "\nGenerated different syntax trees:\n\t- " + + expressions1 + + "\n\t- " + + expressions2); + } + + public static void assertCreateTree(final @NotNull String expr, final @NotNull Expression @NotNull ... expressions) { + assertCreateTree(expr, Arrays.asList(expressions)); + } + + public static void assertCreateTree(final @NotNull String expr, final List expressions) { + final List parsed; + try { + parsed = parse(expr); + } catch (final ParseException e) { + fail("Failed to parse expression: '" + expr + "'", e); + return; + } + + { // Network round-trip + ByteBuf buf = Unpooled.buffer(); + ExprBytesUtils.writeExpressions(expressions, buf); + + List readed = ExprBytesUtils.readExpressions(buf); + buf.release(); + + assertEquals(readed, expressions); + } + + assertEquals( + expressions, + parsed, + () -> "Expression: '" + expr + "' generated unexpected syntax tree:\n\t" + + "- Expected: " + expressions + "\n\t" + + "- Got: " + parsed + ); + } + + public static void assertParseError(final @NotNull String expr, final int column) { + try { + final List expressions = parse(expr); + fail("Expected parse error at column " + column + " for expression: '" + expr + "', instead, it was parsed as: " + expressions); + } catch (final ParseException e) { + assertEquals(column, e.cursor().column(), "Expected parse error at column " + column + " for expression: '" + expr + "'"); + } + } +} diff --git a/parser/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java b/parser/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java index c90b592..8b0ba57 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java +++ b/parser/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.parser; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.parser; import org.junit.jupiter.api.Test; import team.unnamed.mocha.parser.ast.*; diff --git a/runtime-compiler/build.gradle b/runtime-compiler/build.gradle index d9cc89e..2b9ecfd 100644 --- a/runtime-compiler/build.gradle +++ b/runtime-compiler/build.gradle @@ -1,24 +1,24 @@ -plugins { - id "org.jetbrains.kotlin.jvm" -} - -dependencies { - api project(":runtime") - - testImplementation("org.jetbrains.kotlin:kotlin-stdlib:2.3.21") -} - -tasks.register('generateExpectations', Exec) { - workingDir = rootProject.projectDir - def nvmDir = file("${System.getenv('HOME')}/.nvm/versions/node") - executable nvmDir.isDirectory() ? "${nvmDir.listFiles().sort().last()}/bin/node" : 'node' - args 'scripts/generate_expectations.js' -} - -tasks.named("compileTestKotlin") { - enabled = true -} - -tasks.named("test") { - dependsOn tasks.named("generateExpectations") -} +plugins { + id "org.jetbrains.kotlin.jvm" +} + +dependencies { + api project(":runtime") + + testImplementation("org.jetbrains.kotlin:kotlin-stdlib:2.3.21") +} + +tasks.register('generateExpectations', Exec) { + workingDir = rootProject.projectDir + def nvmDir = file("${System.getenv('HOME')}/.nvm/versions/node") + executable nvmDir.isDirectory() ? "${nvmDir.listFiles().sort().last()}/bin/node" : 'node' + args 'scripts/generate_expectations.js' +} + +tasks.named("compileTestKotlin") { + enabled = true +} + +tasks.named("test") { + dependsOn tasks.named("generateExpectations") +} diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java index a495f13..353cbd6 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import com.google.j2objc.annotations.ReflectionSupport; import org.jetbrains.annotations.NotNull; diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java index 77e6d8e..855bd8a 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java @@ -1,375 +1,375 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.MolangParser; -import team.unnamed.mocha.parser.ParseException; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; -import team.unnamed.mocha.runtime.compiled.Named; -import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; -import team.unnamed.mocha.util.ClassFileUtil; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.UncheckedIOException; -import java.lang.classfile.ClassFile; -import java.lang.constant.ClassDesc; -import java.lang.constant.ConstantDescs; -import java.lang.constant.MethodTypeDesc; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Parameter; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Consumer; - -import static java.util.Objects.requireNonNull; -import static team.unnamed.mocha.util.ClassFileUtil.classDescOf; - -public final class MolangCompiler { - private static final AtomicLong CLASS_NAME_COUNTER = new AtomicLong(); - - private final Object entity; - private final Scope scope; - private Consumer postCompile; - private Consumer<@NotNull ParseException> parseExceptionHandler; - - public MolangCompiler(final @Nullable Object entity, final @NotNull Scope scope) { - this.entity = entity; - this.scope = requireNonNull(scope, "scope"); - } - - public @Nullable Object entity() { - return entity; - } - - /** - * Sets the post-compile function, called after a script is compiled to a - * new class but before the class is loaded. The argument is the class - * bytecode, useful for writing it to a file for debugging. - * - *

By default this is null.

- * - * @return This compiler instance. - * @since 3.0.0 - */ - @Contract("_ -> this") - public @NotNull MolangCompiler postCompile(final @Nullable Consumer postCompile) { - this.postCompile = postCompile; - return this; - } - - /** - * Sets the {@link ParseException} handler. Called whenever an internal - * call to {@link MolangParser} from {@link #compile(Reader, Class)} or - * its overloads fails. After the handler runs, the offending compile - * call falls back to compiling an empty body. - * - *

By default this is null.

- * - * @return This compiler instance. - * @since 3.0.0 - */ - @Contract("_ -> this") - public @NotNull MolangCompiler handleParseExceptions(final @Nullable Consumer<@NotNull ParseException> exceptionHandler) { - this.parseExceptionHandler = exceptionHandler; - return this; - } - - public @NotNull T compile(final @NotNull List expressions, final @NotNull Class clazz) { - requireNonNull(expressions, "expressions"); - requireNonNull(clazz, "clazz"); - - if (clazz == MochaFunction.class && expressions.isEmpty()) { - // no expressions and the target type is MochaFunction, - // we know the NOP function - return clazz.cast(MochaFunction.nop()); - } - - if (!clazz.isInterface()) { - throw new IllegalArgumentException("Target type must be an interface: " + clazz.getName()); - } - - Method implementedMethod = null; - for (final Method method : clazz.getDeclaredMethods()) { - if (Modifier.isStatic(method.getModifiers()) || method.isDefault()) { - continue; - } - if (implementedMethod != null) { - throw new IllegalArgumentException("Target type must have only one method: " + clazz.getName()); - } - implementedMethod = method; - } - - if (implementedMethod == null) { - throw new IllegalArgumentException("Target type must have a method to implement: " + clazz.getName()); - } - - final Map argumentParameterIndexes = new CaseInsensitiveStringHashMap<>(); - final ClassDesc[] paramDescs; - - // check method parameter types - { - final Parameter[] parameters = implementedMethod.getParameters(); - paramDescs = new ClassDesc[parameters.length]; - - for (int i = 0; i < parameters.length; ++i) { - final Parameter parameter = parameters[i]; - final Named named = parameter.getDeclaredAnnotation(Named.class); - final String name; - - if (named != null) { - name = named.value(); - } else if (parameter.isNamePresent()) { - name = parameter.getName(); - } else { - throw new IllegalArgumentException("Parameter " + parameter.getName() + " (index " + i - + ") must be annotated with @Named and specify a name"); - } - - argumentParameterIndexes.put(name, i); - paramDescs[i] = classDescOf(parameter.getType()); - } - } - - final ClassDesc interfaceDesc = classDescOf(clazz); - final String scriptClassName = getClass().getPackage().getName() + ".MolangFunctionImpl_" + clazz.getSimpleName() + "_" + implementedMethod.getName() - + "_" + Long.toHexString(CLASS_NAME_COUNTER.incrementAndGet()); - - final ClassDesc scriptClassDesc = ClassDesc.of(scriptClassName); - final ClassDesc returnDesc = classDescOf(implementedMethod.getReturnType()); - final MethodTypeDesc mainMethodTypeDesc = MethodTypeDesc.of(returnDesc, paramDescs); - - // We need to capture requirements and other state from within the lambda - final Map requirements = new CaseInsensitiveStringHashMap<>(); - final Method finalMethod = implementedMethod; - - final byte[] classBytes = ClassFile.of().build(scriptClassDesc, classBuilder -> { - classBuilder.withFlags(Modifier.PUBLIC | Modifier.FINAL); - classBuilder.withInterfaceSymbols(interfaceDesc); - - // compute initial max locals - final int initialMaxLocals; - { - int maxLocals = 1; // 1: this - for (final ClassDesc paramType : paramDescs) { - if (paramType.equals(ConstantDescs.CD_double) || paramType.equals(ConstantDescs.CD_long)) { - maxLocals += 2; - } else { - maxLocals++; - } - } - initialMaxLocals = maxLocals; - } - - // Add main method - classBuilder.withMethod( - finalMethod.getName(), - mainMethodTypeDesc, - Modifier.PUBLIC | Modifier.FINAL, - methodBuilder -> methodBuilder.withCode(codeBuilder -> { - final FunctionCompileState compileState = new FunctionCompileState( - this, scriptClassDesc, codeBuilder, finalMethod, scope, argumentParameterIndexes - ); - compileState.maxLocals(initialMaxLocals); - - // Copy requirements reference so visitor can populate it - final Map stateRequirements = compileState.requirements(); - - if (expressions.isEmpty()) { - ClassFileUtil.addConstZero(codeBuilder, returnDesc); - ClassFileUtil.addReturn(codeBuilder, returnDesc); - } else { - final MolangCompilingVisitor compiler = new MolangCompilingVisitor(compileState); - CompileVisitResult lastVisitResult = null; - - final ExpressionInliner inliner = new ExpressionInliner(new ExpressionInterpreter<>(null, scope), scope); - - for (final Expression expression : expressions) { - lastVisitResult = expression.visit(inliner).visit(compiler); - } - - if (lastVisitResult == null || !lastVisitResult.returned()) { - if (lastVisitResult == null || !returnDesc.equals(lastVisitResult.lastPushedType())) { - ClassFileUtil.addCast( - codeBuilder, - lastVisitResult == null ? ConstantDescs.CD_float : lastVisitResult.lastPushedType(), - returnDesc - ); - } - - compiler.endVisit(); - } - } - - // Copy requirements from compile state to outer map - requirements.putAll(stateRequirements); - })); - - // Add fields for requirements (populated during method compilation above) - for (final Map.Entry entry : requirements.entrySet()) { - final String fieldName = entry.getKey(); - final Object fieldValue = entry.getValue(); - final ClassDesc fieldType = classDescOf(fieldValue.getClass()); - classBuilder.withField(fieldName, fieldType, Modifier.PRIVATE); - } - - // Add constructor - final ClassDesc[] constructorParamDescs = new ClassDesc[requirements.size()]; - int j = 0; - for (final Map.Entry entry : requirements.entrySet()) { - constructorParamDescs[j] = classDescOf(entry.getValue().getClass()); - ++j; - } - - final MethodTypeDesc constructorTypeDesc = MethodTypeDesc.of(ConstantDescs.CD_void, constructorParamDescs); - classBuilder.withMethod( - ConstantDescs.INIT_NAME, - constructorTypeDesc, - Modifier.PUBLIC, - methodBuilder -> methodBuilder.withCode(ctorCode -> { - ctorCode.aload(0); - ctorCode.invokespecial(ConstantDescs.CD_Object, ConstantDescs.INIT_NAME, ConstantDescs.MTD_void); - - int parameterIndex = 0; - for (final Map.Entry entry : requirements.entrySet()) { - final String fieldName = entry.getKey(); - final Object fieldValue = entry.getValue(); - final ClassDesc fieldType = classDescOf(fieldValue.getClass()); - ctorCode.aload(0); // this - ctorCode.aload(parameterIndex + 1); // parameter - ctorCode.putfield(scriptClassDesc, fieldName, fieldType); - parameterIndex++; - } - ctorCode.return_(); - })); - }); - - if (postCompile != null) { - postCompile.accept(classBytes); - } - - final Class compiledClass; - try { - compiledClass = MethodHandles.lookup() - .defineHiddenClass(classBytes, true, MethodHandles.Lookup.ClassOption.NESTMATE) - .lookupClass(); - } catch (final IllegalAccessException e) { - throw new IllegalStateException("Couldn't define hidden class", e); - } - - // find the constructor with the requirements - final Class[] constructorParameterTypes = new Class[requirements.size()]; - final Object[] constructorArguments = new Object[requirements.size()]; - int i = 0; - for (final Object requirement : requirements.values()) { - constructorParameterTypes[i] = requirement.getClass(); - constructorArguments[i] = requirement; - ++i; - } - - final Constructor constructor; - try { - constructor = compiledClass.getDeclaredConstructor(constructorParameterTypes); - } catch (final NoSuchMethodException e) { - throw new IllegalStateException("Couldn't find constructor with parameters " + requirements.keySet(), e); - } - final Object instance; - try { - instance = constructor.newInstance(constructorArguments); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new IllegalStateException("Couldn't instantiate script class", e); - } - return clazz.cast(instance); - } - - /** - * Parses {@code reader} and compiles the resulting AST into the given - * {@code interfaceType}. Parse errors are routed through - * {@link #handleParseExceptions(Consumer)}; on a parse failure the - * compiler falls back to compiling an empty body. - * - * @since 3.0.0 - */ - public @NotNull T compile(final @NotNull Reader reader, final @NotNull Class interfaceType) { - List parsed; - try { - parsed = MolangParser.parseAll(reader); - } catch (final ParseException e) { - if (parseExceptionHandler != null) parseExceptionHandler.accept(e); - parsed = Collections.emptyList(); - } catch (final IOException e) { - throw new UncheckedIOException("Failed to read from given reader", e); - } - return compile(parsed, interfaceType); - } - - /** - * @see #compile(Reader, Class) - * @since 3.0.0 - */ - public @NotNull T compile(final @NotNull String code, final @NotNull Class interfaceType) { - requireNonNull(code, "code"); - try (final StringReader reader = new StringReader(code)) { - return compile(reader, interfaceType); - } - } - - /** - * Compiles the given expressions into a no-arg {@link MochaFunction}. - * - * @since 4.0.4 - */ - public @NotNull MochaFunction compile(final @NotNull List expressions) { - return compile(expressions, MochaFunction.class); - } - - /** - * Parses {@code reader} and compiles the resulting AST into a no-arg - * {@link MochaFunction}. - * - * @since 3.0.0 - */ - public @NotNull MochaFunction compile(final @NotNull Reader reader) { - return compile(reader, MochaFunction.class); - } - - /** - * @see #compile(Reader) - * @since 3.0.0 - */ - public @NotNull MochaFunction compile(final @NotNull String code) { - return compile(code, MochaFunction.class); - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import team.unnamed.mocha.parser.MolangParser; +import team.unnamed.mocha.parser.ParseException; +import team.unnamed.mocha.parser.ast.Expression; +import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; +import team.unnamed.mocha.runtime.compiled.Named; +import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; +import team.unnamed.mocha.util.ClassFileUtil; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.UncheckedIOException; +import java.lang.classfile.ClassFile; +import java.lang.constant.ClassDesc; +import java.lang.constant.ConstantDescs; +import java.lang.constant.MethodTypeDesc; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Parameter; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; + +import static java.util.Objects.requireNonNull; +import static team.unnamed.mocha.util.ClassFileUtil.classDescOf; + +public final class MolangCompiler { + private static final AtomicLong CLASS_NAME_COUNTER = new AtomicLong(); + + private final Object entity; + private final Scope scope; + private Consumer postCompile; + private Consumer<@NotNull ParseException> parseExceptionHandler; + + public MolangCompiler(final @Nullable Object entity, final @NotNull Scope scope) { + this.entity = entity; + this.scope = requireNonNull(scope, "scope"); + } + + public @Nullable Object entity() { + return entity; + } + + /** + * Sets the post-compile function, called after a script is compiled to a + * new class but before the class is loaded. The argument is the class + * bytecode, useful for writing it to a file for debugging. + * + *

By default this is null.

+ * + * @return This compiler instance. + * @since 3.0.0 + */ + @Contract("_ -> this") + public @NotNull MolangCompiler postCompile(final @Nullable Consumer postCompile) { + this.postCompile = postCompile; + return this; + } + + /** + * Sets the {@link ParseException} handler. Called whenever an internal + * call to {@link MolangParser} from {@link #compile(Reader, Class)} or + * its overloads fails. After the handler runs, the offending compile + * call falls back to compiling an empty body. + * + *

By default this is null.

+ * + * @return This compiler instance. + * @since 3.0.0 + */ + @Contract("_ -> this") + public @NotNull MolangCompiler handleParseExceptions(final @Nullable Consumer<@NotNull ParseException> exceptionHandler) { + this.parseExceptionHandler = exceptionHandler; + return this; + } + + public @NotNull T compile(final @NotNull List expressions, final @NotNull Class clazz) { + requireNonNull(expressions, "expressions"); + requireNonNull(clazz, "clazz"); + + if (clazz == MochaFunction.class && expressions.isEmpty()) { + // no expressions and the target type is MochaFunction, + // we know the NOP function + return clazz.cast(MochaFunction.nop()); + } + + if (!clazz.isInterface()) { + throw new IllegalArgumentException("Target type must be an interface: " + clazz.getName()); + } + + Method implementedMethod = null; + for (final Method method : clazz.getDeclaredMethods()) { + if (Modifier.isStatic(method.getModifiers()) || method.isDefault()) { + continue; + } + if (implementedMethod != null) { + throw new IllegalArgumentException("Target type must have only one method: " + clazz.getName()); + } + implementedMethod = method; + } + + if (implementedMethod == null) { + throw new IllegalArgumentException("Target type must have a method to implement: " + clazz.getName()); + } + + final Map argumentParameterIndexes = new CaseInsensitiveStringHashMap<>(); + final ClassDesc[] paramDescs; + + // check method parameter types + { + final Parameter[] parameters = implementedMethod.getParameters(); + paramDescs = new ClassDesc[parameters.length]; + + for (int i = 0; i < parameters.length; ++i) { + final Parameter parameter = parameters[i]; + final Named named = parameter.getDeclaredAnnotation(Named.class); + final String name; + + if (named != null) { + name = named.value(); + } else if (parameter.isNamePresent()) { + name = parameter.getName(); + } else { + throw new IllegalArgumentException("Parameter " + parameter.getName() + " (index " + i + + ") must be annotated with @Named and specify a name"); + } + + argumentParameterIndexes.put(name, i); + paramDescs[i] = classDescOf(parameter.getType()); + } + } + + final ClassDesc interfaceDesc = classDescOf(clazz); + final String scriptClassName = getClass().getPackage().getName() + ".MolangFunctionImpl_" + clazz.getSimpleName() + "_" + implementedMethod.getName() + + "_" + Long.toHexString(CLASS_NAME_COUNTER.incrementAndGet()); + + final ClassDesc scriptClassDesc = ClassDesc.of(scriptClassName); + final ClassDesc returnDesc = classDescOf(implementedMethod.getReturnType()); + final MethodTypeDesc mainMethodTypeDesc = MethodTypeDesc.of(returnDesc, paramDescs); + + // We need to capture requirements and other state from within the lambda + final Map requirements = new CaseInsensitiveStringHashMap<>(); + final Method finalMethod = implementedMethod; + + final byte[] classBytes = ClassFile.of().build(scriptClassDesc, classBuilder -> { + classBuilder.withFlags(Modifier.PUBLIC | Modifier.FINAL); + classBuilder.withInterfaceSymbols(interfaceDesc); + + // compute initial max locals + final int initialMaxLocals; + { + int maxLocals = 1; // 1: this + for (final ClassDesc paramType : paramDescs) { + if (paramType.equals(ConstantDescs.CD_double) || paramType.equals(ConstantDescs.CD_long)) { + maxLocals += 2; + } else { + maxLocals++; + } + } + initialMaxLocals = maxLocals; + } + + // Add main method + classBuilder.withMethod( + finalMethod.getName(), + mainMethodTypeDesc, + Modifier.PUBLIC | Modifier.FINAL, + methodBuilder -> methodBuilder.withCode(codeBuilder -> { + final FunctionCompileState compileState = new FunctionCompileState( + this, scriptClassDesc, codeBuilder, finalMethod, scope, argumentParameterIndexes + ); + compileState.maxLocals(initialMaxLocals); + + // Copy requirements reference so visitor can populate it + final Map stateRequirements = compileState.requirements(); + + if (expressions.isEmpty()) { + ClassFileUtil.addConstZero(codeBuilder, returnDesc); + ClassFileUtil.addReturn(codeBuilder, returnDesc); + } else { + final MolangCompilingVisitor compiler = new MolangCompilingVisitor(compileState); + CompileVisitResult lastVisitResult = null; + + final ExpressionInliner inliner = new ExpressionInliner(new ExpressionInterpreter<>(null, scope), scope); + + for (final Expression expression : expressions) { + lastVisitResult = expression.visit(inliner).visit(compiler); + } + + if (lastVisitResult == null || !lastVisitResult.returned()) { + if (lastVisitResult == null || !returnDesc.equals(lastVisitResult.lastPushedType())) { + ClassFileUtil.addCast( + codeBuilder, + lastVisitResult == null ? ConstantDescs.CD_float : lastVisitResult.lastPushedType(), + returnDesc + ); + } + + compiler.endVisit(); + } + } + + // Copy requirements from compile state to outer map + requirements.putAll(stateRequirements); + })); + + // Add fields for requirements (populated during method compilation above) + for (final Map.Entry entry : requirements.entrySet()) { + final String fieldName = entry.getKey(); + final Object fieldValue = entry.getValue(); + final ClassDesc fieldType = classDescOf(fieldValue.getClass()); + classBuilder.withField(fieldName, fieldType, Modifier.PRIVATE); + } + + // Add constructor + final ClassDesc[] constructorParamDescs = new ClassDesc[requirements.size()]; + int j = 0; + for (final Map.Entry entry : requirements.entrySet()) { + constructorParamDescs[j] = classDescOf(entry.getValue().getClass()); + ++j; + } + + final MethodTypeDesc constructorTypeDesc = MethodTypeDesc.of(ConstantDescs.CD_void, constructorParamDescs); + classBuilder.withMethod( + ConstantDescs.INIT_NAME, + constructorTypeDesc, + Modifier.PUBLIC, + methodBuilder -> methodBuilder.withCode(ctorCode -> { + ctorCode.aload(0); + ctorCode.invokespecial(ConstantDescs.CD_Object, ConstantDescs.INIT_NAME, ConstantDescs.MTD_void); + + int parameterIndex = 0; + for (final Map.Entry entry : requirements.entrySet()) { + final String fieldName = entry.getKey(); + final Object fieldValue = entry.getValue(); + final ClassDesc fieldType = classDescOf(fieldValue.getClass()); + ctorCode.aload(0); // this + ctorCode.aload(parameterIndex + 1); // parameter + ctorCode.putfield(scriptClassDesc, fieldName, fieldType); + parameterIndex++; + } + ctorCode.return_(); + })); + }); + + if (postCompile != null) { + postCompile.accept(classBytes); + } + + final Class compiledClass; + try { + compiledClass = MethodHandles.lookup() + .defineHiddenClass(classBytes, true, MethodHandles.Lookup.ClassOption.NESTMATE) + .lookupClass(); + } catch (final IllegalAccessException e) { + throw new IllegalStateException("Couldn't define hidden class", e); + } + + // find the constructor with the requirements + final Class[] constructorParameterTypes = new Class[requirements.size()]; + final Object[] constructorArguments = new Object[requirements.size()]; + int i = 0; + for (final Object requirement : requirements.values()) { + constructorParameterTypes[i] = requirement.getClass(); + constructorArguments[i] = requirement; + ++i; + } + + final Constructor constructor; + try { + constructor = compiledClass.getDeclaredConstructor(constructorParameterTypes); + } catch (final NoSuchMethodException e) { + throw new IllegalStateException("Couldn't find constructor with parameters " + requirements.keySet(), e); + } + final Object instance; + try { + instance = constructor.newInstance(constructorArguments); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException("Couldn't instantiate script class", e); + } + return clazz.cast(instance); + } + + /** + * Parses {@code reader} and compiles the resulting AST into the given + * {@code interfaceType}. Parse errors are routed through + * {@link #handleParseExceptions(Consumer)}; on a parse failure the + * compiler falls back to compiling an empty body. + * + * @since 3.0.0 + */ + public @NotNull T compile(final @NotNull Reader reader, final @NotNull Class interfaceType) { + List parsed; + try { + parsed = MolangParser.parseAll(reader); + } catch (final ParseException e) { + if (parseExceptionHandler != null) parseExceptionHandler.accept(e); + parsed = Collections.emptyList(); + } catch (final IOException e) { + throw new UncheckedIOException("Failed to read from given reader", e); + } + return compile(parsed, interfaceType); + } + + /** + * @see #compile(Reader, Class) + * @since 3.0.0 + */ + public @NotNull T compile(final @NotNull String code, final @NotNull Class interfaceType) { + requireNonNull(code, "code"); + try (final StringReader reader = new StringReader(code)) { + return compile(reader, interfaceType); + } + } + + /** + * Compiles the given expressions into a no-arg {@link MochaFunction}. + * + * @since 4.0.4 + */ + public @NotNull MochaFunction compile(final @NotNull List expressions) { + return compile(expressions, MochaFunction.class); + } + + /** + * Parses {@code reader} and compiles the resulting AST into a no-arg + * {@link MochaFunction}. + * + * @since 3.0.0 + */ + public @NotNull MochaFunction compile(final @NotNull Reader reader) { + return compile(reader, MochaFunction.class); + } + + /** + * @see #compile(Reader) + * @since 3.0.0 + */ + public @NotNull MochaFunction compile(final @NotNull String code) { + return compile(code, MochaFunction.class); + } +} diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java index bba9470..a2bda2a 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java @@ -1,650 +1,650 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; - -import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.parser.ast.*; -import team.unnamed.mocha.runtime.binding.Entity; -import team.unnamed.mocha.runtime.binding.JavaFieldBinding; -import team.unnamed.mocha.runtime.binding.JavaFunction; -import team.unnamed.mocha.runtime.binding.JavaObjectBinding; -import team.unnamed.mocha.runtime.value.Function; -import team.unnamed.mocha.runtime.value.NumberValue; -import team.unnamed.mocha.runtime.value.ObjectValue; -import team.unnamed.mocha.runtime.value.Value; -import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; -import team.unnamed.mocha.util.ClassFileUtil; - -import java.lang.classfile.CodeBuilder; -import java.lang.classfile.Label; -import java.lang.constant.ClassDesc; -import java.lang.constant.MethodTypeDesc; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Parameter; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import static java.lang.constant.ConstantDescs.*; -import static team.unnamed.mocha.util.ClassFileUtil.*; - -final class MolangCompilingVisitor implements ExpressionVisitor { - - private final CodeBuilder codeBuilder; - private final Method method; - - private final FunctionCompileState functionCompileState; - private final Map requirements; - private final Map argumentParameterIndexes; - - private final Map localsByName = new CaseInsensitiveStringHashMap<>(); - - private final ExpressionVisitor scopeResolver; - - /** - * The method return type - */ - private final ClassDesc methodReturnType; - /** - * The type that the current visitor method is expecting - * to be pushed to the stack. - */ - private ClassDesc expectedType; - - MolangCompilingVisitor(final @NotNull FunctionCompileState compileState) { - this.functionCompileState = compileState; - this.codeBuilder = compileState.codeBuilder(); - this.method = compileState.method(); - this.requirements = compileState.requirements(); - this.argumentParameterIndexes = compileState.argumentParameterIndexes(); - - this.methodReturnType = classDescOf(method.getReturnType()); - expectedType = methodReturnType; - - this.scopeResolver = new ExpressionVisitor<>() { - @Override - public @NotNull Value visitIdentifier(final @NotNull IdentifierExpression expression) { - return functionCompileState.scope().get(expression.name()); - } - - @Override - public @NotNull Value visitAccess(final @NotNull AccessExpression expression) { - final Value object = expression.object().visit(this); - if (object instanceof ObjectValue) { - return ((ObjectValue) object).get(expression.property()); - } else { - return NumberValue.zero(); - } - } - - @Override - public @NotNull Value visit(final @NotNull Expression expression) { - return NumberValue.zero(); - } - }; - } - - @Override - public CompileVisitResult visitBinary(final @NotNull BinaryExpression expression) { - final BinaryExpression.Op op = expression.op(); - - if (op == BinaryExpression.Op.ASSIGN) { - final Expression left = expression.left(); - if (left instanceof AccessExpression) { - final Expression objectExpr = ((AccessExpression) left).object(); - if (objectExpr instanceof IdentifierExpression) { - final String name = ((IdentifierExpression) objectExpr).name(); - final String property = ((AccessExpression) left).property(); - - if (name.equals("temp") || name.equals("t")) { - final CompileVisitResult result = expression.right().visit(this); - final int localIndex = localsByName.computeIfAbsent(property, k -> { - int index = functionCompileState.maxLocals(); - if (result.lastPushedType() != null && - (result.lastPushedType().equals(CD_double) || result.lastPushedType().equals(CD_long))) { - functionCompileState.maxLocals(index + 2); - } else { - functionCompileState.maxLocals(index + 1); - } - return index; - }); - codeBuilder.fstore(localIndex); - return null; - } - } - } - } - - final ClassDesc currentExpectedType = expectedType; - - //@formatter:off - switch (op) { - case AND: { - expectedType = CD_boolean; - expression.left().visit(this); - Label falseLabel = codeBuilder.newLabel(); - codeBuilder.ifeq(falseLabel); - expression.right().visit(this); - Label trueEnd = codeBuilder.newLabel(); - codeBuilder.ifeq(falseLabel); - addConst1(currentExpectedType); - codeBuilder.goto_(trueEnd); - codeBuilder.labelBinding(falseLabel); - addConst0(currentExpectedType); - codeBuilder.labelBinding(trueEnd); - expectedType = currentExpectedType; - return new CompileVisitResult(currentExpectedType); - } - case OR: { - expectedType = CD_boolean; - expression.left().visit(this); - Label trueLabel = codeBuilder.newLabel(); - codeBuilder.ifne(trueLabel); - expression.right().visit(this); - Label falseLabel = codeBuilder.newLabel(); - codeBuilder.ifeq(falseLabel); - codeBuilder.labelBinding(trueLabel); - addConst1(currentExpectedType); - Label end = codeBuilder.newLabel(); - codeBuilder.goto_(end); - codeBuilder.labelBinding(falseLabel); - addConst0(currentExpectedType); - codeBuilder.labelBinding(end); - expectedType = currentExpectedType; - return new CompileVisitResult(currentExpectedType); - } - case EQ: - case NEQ: - case LT: - case LTE: - case GT: - case GTE: { - expectedType = CD_float; - expression.left().visit(this); // pushes lhs value to stack - expression.right().visit(this); // pushes rhs value to stack - expectedType = currentExpectedType; - - codeBuilder.fcmpl(); - - Label trueLabel = codeBuilder.newLabel(); - Label end = codeBuilder.newLabel(); - - switch (op) { - case LT -> codeBuilder.iflt(trueLabel); - case LTE -> codeBuilder.ifle(trueLabel); - case GT -> codeBuilder.ifgt(trueLabel); - case GTE -> codeBuilder.ifge(trueLabel); - case EQ -> codeBuilder.ifeq(trueLabel); - case NEQ -> codeBuilder.ifne(trueLabel); - default -> throw new IllegalStateException(); - } - addConst0(expectedType == null ? CD_boolean : expectedType); - codeBuilder.goto_(end); - codeBuilder.labelBinding(trueLabel); - addConst1(expectedType == null ? CD_boolean : expectedType); - codeBuilder.labelBinding(end); - return new CompileVisitResult(expectedType == null ? CD_boolean : expectedType); - } - case ADD: { - expectedType = CD_float; - expression.left().visit(this); - expression.right().visit(this); - expectedType = currentExpectedType; - codeBuilder.fadd(); - return CompileVisitResult.FLOAT; - } - case SUB: { - expectedType = CD_float; - expression.left().visit(this); - expression.right().visit(this); - expectedType = currentExpectedType; - codeBuilder.fsub(); - return CompileVisitResult.FLOAT; - } - case MUL: { - expectedType = CD_float; - expression.left().visit(this); - expression.right().visit(this); - expectedType = currentExpectedType; - codeBuilder.fmul(); - return CompileVisitResult.FLOAT; - } - case DIV: { - expectedType = CD_float; - expression.left().visit(this); // pushes lhs value to stack - expression.right().visit(this); // pushes rhs value to stack - expectedType = currentExpectedType; - codeBuilder.fdiv(); - return CompileVisitResult.FLOAT; - } - case ARROW: - case NULL_COALESCE: - case CONDITIONAL: - break; - } - //@formatter:on - return null; - } - - public void endVisit() { - ClassFileUtil.addReturn(codeBuilder, methodReturnType); - } - - @Override - public @NotNull CompileVisitResult visitFloat(final @NotNull FloatExpression expression) { - final float value = expression.value(); - if (expectedType != null && expectedType.equals(CD_void)) { - // nothing! - return CompileVisitResult.VOID; - } else if (expectedType == null || expectedType.equals(CD_float)) { - // expects a float, happy! - codeBuilder.loadConstant(value); - return CompileVisitResult.FLOAT; - } else if (expectedType.equals(CD_boolean)) { - // expects a boolean, push boolean - if (value != 0.0D) { - codeBuilder.iconst_1(); - } else { - codeBuilder.iconst_0(); - } - return CompileVisitResult.BOOLEAN; - } else if (expectedType.equals(CD_int)) { - // expects an int, push int - codeBuilder.loadConstant((int) value); - return CompileVisitResult.INT; - } else if (expectedType.equals(CD_long)) { - // expects a long, push long - codeBuilder.loadConstant((long) value); - return CompileVisitResult.LONG; - } else if (expectedType.equals(CD_double)) { - // expects a double, push double - codeBuilder.loadConstant((double) value); - return CompileVisitResult.DOUBLE; - } else { - System.err.println("[warning] expected type " + expectedType + " has no possible cast from float (" + expression + ")"); - // evaluate to zero - addConstZero(codeBuilder, expectedType); - return new CompileVisitResult(expectedType); - } - } - - @Override - public @NotNull CompileVisitResult visitString(final @NotNull StringExpression expression) { - if (expectedType != null && expectedType.equals(CD_void)) { - // nothing! - return CompileVisitResult.VOID; - } else if (expectedType == null || expectedType.equals(CD_String)) { - // expected a string, happy - codeBuilder.loadConstant(expression.value()); - return CompileVisitResult.STRING; - } else { - // evaluate to zero - addConstZero(codeBuilder, expectedType); - return new CompileVisitResult(expectedType); - } - } - - @Override - public @NotNull CompileVisitResult visitUnary(final @NotNull UnaryExpression expression) { - switch (expression.op()) { - case RETURN: { - expectedType = methodReturnType; - expression.expression().visit(this); - expectedType = null; - ClassFileUtil.addReturn(codeBuilder, methodReturnType); - return new CompileVisitResult(methodReturnType, true); - } - case LOGICAL_NEGATION: { - if (expectedType != null && expectedType.equals(CD_void)) { - // void, - // we must evaluate in case of weird expressions - // like: !query.print('hello') - // won't push anything since expectedType is set to voidType - expression.expression().visit(this); - return CompileVisitResult.VOID; - } - - final ClassDesc currentExpectedType = expectedType; - - if (currentExpectedType != null && !currentExpectedType.isPrimitive()) { - // an unknown Object type, evaluate without pushing anything - // and then just push null in the stack - expectedType = CD_void; // set to void so that doesn't push anything - expression.expression().visit(this); - expectedType = currentExpectedType; - addConstZero(codeBuilder, currentExpectedType); - return new CompileVisitResult(currentExpectedType); - } - - // todo: wrap primitives to their wrapper class if needed - - expectedType = CD_boolean; - expression.expression().visit(this); // push boolean value to stack - expectedType = currentExpectedType; - - if (currentExpectedType != null && currentExpectedType.equals(CD_boolean)) { - // For boolean, leave value on stack and branch - // We need: if (value != 0) push 0 else push 1 - Label pushZero = codeBuilder.newLabel(); - Label end = codeBuilder.newLabel(); - codeBuilder.ifne(pushZero); - codeBuilder.iconst_1(); - codeBuilder.goto_(end); - codeBuilder.labelBinding(pushZero); - codeBuilder.iconst_0(); - codeBuilder.labelBinding(end); - return CompileVisitResult.BOOLEAN; - } - - Label pushConst0 = codeBuilder.newLabel(); - Label end = codeBuilder.newLabel(); - codeBuilder.ifne(pushConst0); - addConst1(currentExpectedType); - codeBuilder.goto_(end); - codeBuilder.labelBinding(pushConst0); - addConst0(currentExpectedType); - codeBuilder.labelBinding(end); - return new CompileVisitResult(currentExpectedType); - } - case ARITHMETICAL_NEGATION: { - final CompileVisitResult result = expression.expression().visit(this); // push value to stack - if (result.is(CD_double)) { - codeBuilder.dneg(); - } else if (result.is(CD_long)) { - codeBuilder.lneg(); - } else if (result.is(CD_float)) { - codeBuilder.fneg(); - } else if (result.is(CD_int)) { - codeBuilder.ineg(); - } else if (result.is(CD_boolean)) { - // logical negation - codeBuilder.iconst_1(); - codeBuilder.ixor(); - } else { - throw new IllegalStateException("Unsupported type for negation: " + result); - } - break; - } - default: - throw new UnsupportedOperationException("Unsupported unary operator: " + expression.op()); - } - return null; - } - - @Override - public @NotNull CompileVisitResult visitTernaryConditional(final @NotNull TernaryConditionalExpression expression) { - final Expression trueExpr = expression.trueExpression(); - final Expression falseExpr = expression.falseExpression(); - - final ClassDesc currentExpectedType = expectedType; - expectedType = CD_boolean; - final CompileVisitResult conditionRes = expression.condition().visit(this); - expectedType = currentExpectedType; - - if (conditionRes != null && conditionRes.lastPushedType() != null - && !conditionRes.is(CD_boolean) && !conditionRes.is(CD_int)) { - addConstZero(codeBuilder, conditionRes.lastPushedType()); - if (conditionRes.is(CD_double)) { - codeBuilder.dcmpl(); - } else if (conditionRes.is(CD_float)) { - codeBuilder.fcmpl(); - } else if (conditionRes.is(CD_long)) { - codeBuilder.lcmp(); - } else { - throw new IllegalStateException("Unsupported type for comparison: " + conditionRes); - } - } - - Label falseLabel = codeBuilder.newLabel(); - Label end = codeBuilder.newLabel(); - codeBuilder.ifeq(falseLabel); - trueExpr.visit(this); - codeBuilder.goto_(end); - codeBuilder.labelBinding(falseLabel); - falseExpr.visit(this); - codeBuilder.labelBinding(end); - return new CompileVisitResult(currentExpectedType); - } - - @Override - public CompileVisitResult visitIdentifier(final @NotNull IdentifierExpression expression) { - final String name = expression.name(); - final Integer paramIndex = argumentParameterIndexes.get(name); - if (paramIndex == null) { - throw new IllegalStateException("Unknown variable: " + name); - } - - final Parameter[] parameters = method.getParameters(); - final Parameter parameter = parameters[paramIndex]; - int loadIndex = 1; - for (int i = 0; i < paramIndex; i++) { - final Parameter param = parameters[i]; - final Class paramType = param.getType(); - if (paramType.equals(double.class) || paramType.equals(long.class)) { - loadIndex += 2; - } else { - loadIndex += 1; - } - } - - final ClassDesc parameterType = classDescOf(parameter.getType()); - - ClassFileUtil.addLoad(codeBuilder, loadIndex, parameterType); - - if (expectedType == null) { - // we are free to use anything, no need to cast - return new CompileVisitResult(parameterType); - } - - // convert to the expected type - ClassFileUtil.addCast(codeBuilder, parameterType, expectedType); - return new CompileVisitResult(expectedType); - } - - @Override - public CompileVisitResult visitAccess(final @NotNull AccessExpression expression) { - final Expression objectExpr = expression.object(); - final String property = expression.property(); - - if (objectExpr instanceof IdentifierExpression) { - final String name = ((IdentifierExpression) objectExpr).name(); - if (name.equals("temp") || name.equals("t")) { - // temps are locals - final Integer localIndex = localsByName.get(property); - if (localIndex == null) { - codeBuilder.fconst_0(); - } else { - codeBuilder.fload(localIndex); - } - return CompileVisitResult.FLOAT; - } - } - - final Value objectValue = objectExpr.visit(this.scopeResolver); - - if (objectValue instanceof ObjectValue) { - final ObjectValue actualObjectValue = (ObjectValue) objectValue; - if (actualObjectValue instanceof JavaObjectBinding) { - final JavaFieldBinding javaFieldBinding = ((JavaObjectBinding) actualObjectValue).getField(property); - if (javaFieldBinding == null) { - // push zero only - codeBuilder.fconst_0(); - } else if (javaFieldBinding.constant()) { - // inline const - codeBuilder.loadConstant(javaFieldBinding.get().getAsNumber()); - } else { - final Field field = javaFieldBinding.field(); - if (Modifier.isStatic(field.getModifiers())) { - codeBuilder.getstatic( - classDescOf(field.getDeclaringClass()), - field.getName(), - classDescOf(field.getType()) - ); - } - } - } - } - - return null; - } - - @Override - public CompileVisitResult visitCall(final @NotNull CallExpression expression) { - final ClassDesc targetType = this.expectedType; - final Expression functionExpr = expression.function(); - - final Value functionValue = functionExpr.visit(this.scopeResolver); - - if (!(functionValue instanceof Function)) { - // not a function, just add 0 - codeBuilder.fconst_0(); - return CompileVisitResult.FLOAT; - } - - final Function function = (Function) functionValue; - - if (function instanceof JavaFunction) { - // we can compile to directly call this function (Java Method) - final JavaFunction javaFunction = (JavaFunction) function; - final Method nativeMethod = javaFunction.method(); - final Parameter[] parameters = nativeMethod.getParameters(); - final List arguments = expression.arguments(); - - final ClassDesc[] ctParameters = new ClassDesc[parameters.length]; - for (int i = 0; i < parameters.length; i++) { - ctParameters[i] = classDescOf(parameters[i].getType()); - } - - final boolean isStatic = Modifier.isStatic(nativeMethod.getModifiers()); - - // load instance - if (!isStatic) { - final Object object = javaFunction.object(); - final String fieldName = object.getClass().getSimpleName().toLowerCase(Locale.ROOT) + Integer.toHexString(object.hashCode()); - requirements.put(fieldName, object); - - final ClassDesc requirementType = classDescOf(object.getClass()); - - // we must load object - codeBuilder.aload(0); - codeBuilder.getfield(functionCompileState.classDesc(), fieldName, requirementType); - } - - // load arguments - final Iterator it = arguments.iterator(); - for (int i = 0; i < parameters.length; i++) { - final Parameter parameter = parameters[i]; - final ClassDesc paramType = ctParameters[i]; - - if (parameter.isAnnotationPresent(Entity.class)) { - Object entity = functionCompileState.compiler().entity(); - if (entity == null || !parameter.getType().isInstance(entity)) { - // load null - addConstZero(codeBuilder, paramType); - } else { - // add entity requirement - requirements.put("__entity__", entity); - - // load entity requirement (field) - codeBuilder.aload(0); // load this - codeBuilder.getfield( - functionCompileState.classDesc(), - "__entity__", - paramType - ); - } - continue; - } - - if (!it.hasNext()) { - addConstZero(codeBuilder, paramType); - continue; - } - - // Set the expected type, then load - this.expectedType = paramType; - it.next().visit(this); - } - - final ClassDesc declaringClassDesc = classDescOf(nativeMethod.getDeclaringClass()); - final ClassDesc returnTypeDesc = classDescOf(nativeMethod.getReturnType()); - final MethodTypeDesc methodTypeDesc = MethodTypeDesc.of(returnTypeDesc, ctParameters); - - if (isStatic) { - // invoke static - codeBuilder.invokestatic(declaringClassDesc, nativeMethod.getName(), methodTypeDesc); - } else { - codeBuilder.invokevirtual(declaringClassDesc, nativeMethod.getName(), methodTypeDesc); - } - - if (nativeMethod.getReturnType() == void.class) { - if (targetType != null && !targetType.equals(CD_void)) { - addConstZero(codeBuilder, targetType); - return new CompileVisitResult(targetType); - } - return CompileVisitResult.VOID; - } else { - if (targetType != null && !returnTypeDesc.equals(targetType)) { - ClassFileUtil.addCast(codeBuilder, returnTypeDesc, targetType); - return new CompileVisitResult(targetType); - } - return new CompileVisitResult(returnTypeDesc); - } - } else { - throw new UnsupportedOperationException("Not supporting non-Java functions yet"); - } - } - - @Override - public CompileVisitResult visit(final @NotNull Expression expression) { - throw new UnsupportedOperationException("Unsupported expression type: " + expression); - } - - private void addConst0(final ClassDesc type) { - if (type == null || type.equals(CD_float)) { - codeBuilder.fconst_0(); - } else if (type.equals(CD_double)) { - codeBuilder.dconst_0(); - } else if (type.equals(CD_long)) { - codeBuilder.lconst_0(); - } else { - codeBuilder.iconst_0(); - } - } - - private void addConst1(final ClassDesc type) { - if (type == null || type.equals(CD_float)) { - codeBuilder.fconst_1(); - } else if (type.equals(CD_double)) { - codeBuilder.dconst_1(); - } else if (type.equals(CD_long)) { - codeBuilder.lconst_1(); - } else { - codeBuilder.iconst_1(); - } - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; + +import org.jetbrains.annotations.NotNull; +import team.unnamed.mocha.parser.ast.*; +import team.unnamed.mocha.runtime.binding.Entity; +import team.unnamed.mocha.runtime.binding.JavaFieldBinding; +import team.unnamed.mocha.runtime.binding.JavaFunction; +import team.unnamed.mocha.runtime.binding.JavaObjectBinding; +import team.unnamed.mocha.runtime.value.Function; +import team.unnamed.mocha.runtime.value.NumberValue; +import team.unnamed.mocha.runtime.value.ObjectValue; +import team.unnamed.mocha.runtime.value.Value; +import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; +import team.unnamed.mocha.util.ClassFileUtil; + +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.Label; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Parameter; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import static java.lang.constant.ConstantDescs.*; +import static team.unnamed.mocha.util.ClassFileUtil.*; + +final class MolangCompilingVisitor implements ExpressionVisitor { + + private final CodeBuilder codeBuilder; + private final Method method; + + private final FunctionCompileState functionCompileState; + private final Map requirements; + private final Map argumentParameterIndexes; + + private final Map localsByName = new CaseInsensitiveStringHashMap<>(); + + private final ExpressionVisitor scopeResolver; + + /** + * The method return type + */ + private final ClassDesc methodReturnType; + /** + * The type that the current visitor method is expecting + * to be pushed to the stack. + */ + private ClassDesc expectedType; + + MolangCompilingVisitor(final @NotNull FunctionCompileState compileState) { + this.functionCompileState = compileState; + this.codeBuilder = compileState.codeBuilder(); + this.method = compileState.method(); + this.requirements = compileState.requirements(); + this.argumentParameterIndexes = compileState.argumentParameterIndexes(); + + this.methodReturnType = classDescOf(method.getReturnType()); + expectedType = methodReturnType; + + this.scopeResolver = new ExpressionVisitor<>() { + @Override + public @NotNull Value visitIdentifier(final @NotNull IdentifierExpression expression) { + return functionCompileState.scope().get(expression.name()); + } + + @Override + public @NotNull Value visitAccess(final @NotNull AccessExpression expression) { + final Value object = expression.object().visit(this); + if (object instanceof ObjectValue) { + return ((ObjectValue) object).get(expression.property()); + } else { + return NumberValue.zero(); + } + } + + @Override + public @NotNull Value visit(final @NotNull Expression expression) { + return NumberValue.zero(); + } + }; + } + + @Override + public CompileVisitResult visitBinary(final @NotNull BinaryExpression expression) { + final BinaryExpression.Op op = expression.op(); + + if (op == BinaryExpression.Op.ASSIGN) { + final Expression left = expression.left(); + if (left instanceof AccessExpression) { + final Expression objectExpr = ((AccessExpression) left).object(); + if (objectExpr instanceof IdentifierExpression) { + final String name = ((IdentifierExpression) objectExpr).name(); + final String property = ((AccessExpression) left).property(); + + if (name.equals("temp") || name.equals("t")) { + final CompileVisitResult result = expression.right().visit(this); + final int localIndex = localsByName.computeIfAbsent(property, k -> { + int index = functionCompileState.maxLocals(); + if (result.lastPushedType() != null && + (result.lastPushedType().equals(CD_double) || result.lastPushedType().equals(CD_long))) { + functionCompileState.maxLocals(index + 2); + } else { + functionCompileState.maxLocals(index + 1); + } + return index; + }); + codeBuilder.fstore(localIndex); + return null; + } + } + } + } + + final ClassDesc currentExpectedType = expectedType; + + //@formatter:off + switch (op) { + case AND: { + expectedType = CD_boolean; + expression.left().visit(this); + Label falseLabel = codeBuilder.newLabel(); + codeBuilder.ifeq(falseLabel); + expression.right().visit(this); + Label trueEnd = codeBuilder.newLabel(); + codeBuilder.ifeq(falseLabel); + addConst1(currentExpectedType); + codeBuilder.goto_(trueEnd); + codeBuilder.labelBinding(falseLabel); + addConst0(currentExpectedType); + codeBuilder.labelBinding(trueEnd); + expectedType = currentExpectedType; + return new CompileVisitResult(currentExpectedType); + } + case OR: { + expectedType = CD_boolean; + expression.left().visit(this); + Label trueLabel = codeBuilder.newLabel(); + codeBuilder.ifne(trueLabel); + expression.right().visit(this); + Label falseLabel = codeBuilder.newLabel(); + codeBuilder.ifeq(falseLabel); + codeBuilder.labelBinding(trueLabel); + addConst1(currentExpectedType); + Label end = codeBuilder.newLabel(); + codeBuilder.goto_(end); + codeBuilder.labelBinding(falseLabel); + addConst0(currentExpectedType); + codeBuilder.labelBinding(end); + expectedType = currentExpectedType; + return new CompileVisitResult(currentExpectedType); + } + case EQ: + case NEQ: + case LT: + case LTE: + case GT: + case GTE: { + expectedType = CD_float; + expression.left().visit(this); // pushes lhs value to stack + expression.right().visit(this); // pushes rhs value to stack + expectedType = currentExpectedType; + + codeBuilder.fcmpl(); + + Label trueLabel = codeBuilder.newLabel(); + Label end = codeBuilder.newLabel(); + + switch (op) { + case LT -> codeBuilder.iflt(trueLabel); + case LTE -> codeBuilder.ifle(trueLabel); + case GT -> codeBuilder.ifgt(trueLabel); + case GTE -> codeBuilder.ifge(trueLabel); + case EQ -> codeBuilder.ifeq(trueLabel); + case NEQ -> codeBuilder.ifne(trueLabel); + default -> throw new IllegalStateException(); + } + addConst0(expectedType == null ? CD_boolean : expectedType); + codeBuilder.goto_(end); + codeBuilder.labelBinding(trueLabel); + addConst1(expectedType == null ? CD_boolean : expectedType); + codeBuilder.labelBinding(end); + return new CompileVisitResult(expectedType == null ? CD_boolean : expectedType); + } + case ADD: { + expectedType = CD_float; + expression.left().visit(this); + expression.right().visit(this); + expectedType = currentExpectedType; + codeBuilder.fadd(); + return CompileVisitResult.FLOAT; + } + case SUB: { + expectedType = CD_float; + expression.left().visit(this); + expression.right().visit(this); + expectedType = currentExpectedType; + codeBuilder.fsub(); + return CompileVisitResult.FLOAT; + } + case MUL: { + expectedType = CD_float; + expression.left().visit(this); + expression.right().visit(this); + expectedType = currentExpectedType; + codeBuilder.fmul(); + return CompileVisitResult.FLOAT; + } + case DIV: { + expectedType = CD_float; + expression.left().visit(this); // pushes lhs value to stack + expression.right().visit(this); // pushes rhs value to stack + expectedType = currentExpectedType; + codeBuilder.fdiv(); + return CompileVisitResult.FLOAT; + } + case ARROW: + case NULL_COALESCE: + case CONDITIONAL: + break; + } + //@formatter:on + return null; + } + + public void endVisit() { + ClassFileUtil.addReturn(codeBuilder, methodReturnType); + } + + @Override + public @NotNull CompileVisitResult visitFloat(final @NotNull FloatExpression expression) { + final float value = expression.value(); + if (expectedType != null && expectedType.equals(CD_void)) { + // nothing! + return CompileVisitResult.VOID; + } else if (expectedType == null || expectedType.equals(CD_float)) { + // expects a float, happy! + codeBuilder.loadConstant(value); + return CompileVisitResult.FLOAT; + } else if (expectedType.equals(CD_boolean)) { + // expects a boolean, push boolean + if (value != 0.0D) { + codeBuilder.iconst_1(); + } else { + codeBuilder.iconst_0(); + } + return CompileVisitResult.BOOLEAN; + } else if (expectedType.equals(CD_int)) { + // expects an int, push int + codeBuilder.loadConstant((int) value); + return CompileVisitResult.INT; + } else if (expectedType.equals(CD_long)) { + // expects a long, push long + codeBuilder.loadConstant((long) value); + return CompileVisitResult.LONG; + } else if (expectedType.equals(CD_double)) { + // expects a double, push double + codeBuilder.loadConstant((double) value); + return CompileVisitResult.DOUBLE; + } else { + System.err.println("[warning] expected type " + expectedType + " has no possible cast from float (" + expression + ")"); + // evaluate to zero + addConstZero(codeBuilder, expectedType); + return new CompileVisitResult(expectedType); + } + } + + @Override + public @NotNull CompileVisitResult visitString(final @NotNull StringExpression expression) { + if (expectedType != null && expectedType.equals(CD_void)) { + // nothing! + return CompileVisitResult.VOID; + } else if (expectedType == null || expectedType.equals(CD_String)) { + // expected a string, happy + codeBuilder.loadConstant(expression.value()); + return CompileVisitResult.STRING; + } else { + // evaluate to zero + addConstZero(codeBuilder, expectedType); + return new CompileVisitResult(expectedType); + } + } + + @Override + public @NotNull CompileVisitResult visitUnary(final @NotNull UnaryExpression expression) { + switch (expression.op()) { + case RETURN: { + expectedType = methodReturnType; + expression.expression().visit(this); + expectedType = null; + ClassFileUtil.addReturn(codeBuilder, methodReturnType); + return new CompileVisitResult(methodReturnType, true); + } + case LOGICAL_NEGATION: { + if (expectedType != null && expectedType.equals(CD_void)) { + // void, + // we must evaluate in case of weird expressions + // like: !query.print('hello') + // won't push anything since expectedType is set to voidType + expression.expression().visit(this); + return CompileVisitResult.VOID; + } + + final ClassDesc currentExpectedType = expectedType; + + if (currentExpectedType != null && !currentExpectedType.isPrimitive()) { + // an unknown Object type, evaluate without pushing anything + // and then just push null in the stack + expectedType = CD_void; // set to void so that doesn't push anything + expression.expression().visit(this); + expectedType = currentExpectedType; + addConstZero(codeBuilder, currentExpectedType); + return new CompileVisitResult(currentExpectedType); + } + + // todo: wrap primitives to their wrapper class if needed + + expectedType = CD_boolean; + expression.expression().visit(this); // push boolean value to stack + expectedType = currentExpectedType; + + if (currentExpectedType != null && currentExpectedType.equals(CD_boolean)) { + // For boolean, leave value on stack and branch + // We need: if (value != 0) push 0 else push 1 + Label pushZero = codeBuilder.newLabel(); + Label end = codeBuilder.newLabel(); + codeBuilder.ifne(pushZero); + codeBuilder.iconst_1(); + codeBuilder.goto_(end); + codeBuilder.labelBinding(pushZero); + codeBuilder.iconst_0(); + codeBuilder.labelBinding(end); + return CompileVisitResult.BOOLEAN; + } + + Label pushConst0 = codeBuilder.newLabel(); + Label end = codeBuilder.newLabel(); + codeBuilder.ifne(pushConst0); + addConst1(currentExpectedType); + codeBuilder.goto_(end); + codeBuilder.labelBinding(pushConst0); + addConst0(currentExpectedType); + codeBuilder.labelBinding(end); + return new CompileVisitResult(currentExpectedType); + } + case ARITHMETICAL_NEGATION: { + final CompileVisitResult result = expression.expression().visit(this); // push value to stack + if (result.is(CD_double)) { + codeBuilder.dneg(); + } else if (result.is(CD_long)) { + codeBuilder.lneg(); + } else if (result.is(CD_float)) { + codeBuilder.fneg(); + } else if (result.is(CD_int)) { + codeBuilder.ineg(); + } else if (result.is(CD_boolean)) { + // logical negation + codeBuilder.iconst_1(); + codeBuilder.ixor(); + } else { + throw new IllegalStateException("Unsupported type for negation: " + result); + } + break; + } + default: + throw new UnsupportedOperationException("Unsupported unary operator: " + expression.op()); + } + return null; + } + + @Override + public @NotNull CompileVisitResult visitTernaryConditional(final @NotNull TernaryConditionalExpression expression) { + final Expression trueExpr = expression.trueExpression(); + final Expression falseExpr = expression.falseExpression(); + + final ClassDesc currentExpectedType = expectedType; + expectedType = CD_boolean; + final CompileVisitResult conditionRes = expression.condition().visit(this); + expectedType = currentExpectedType; + + if (conditionRes != null && conditionRes.lastPushedType() != null + && !conditionRes.is(CD_boolean) && !conditionRes.is(CD_int)) { + addConstZero(codeBuilder, conditionRes.lastPushedType()); + if (conditionRes.is(CD_double)) { + codeBuilder.dcmpl(); + } else if (conditionRes.is(CD_float)) { + codeBuilder.fcmpl(); + } else if (conditionRes.is(CD_long)) { + codeBuilder.lcmp(); + } else { + throw new IllegalStateException("Unsupported type for comparison: " + conditionRes); + } + } + + Label falseLabel = codeBuilder.newLabel(); + Label end = codeBuilder.newLabel(); + codeBuilder.ifeq(falseLabel); + trueExpr.visit(this); + codeBuilder.goto_(end); + codeBuilder.labelBinding(falseLabel); + falseExpr.visit(this); + codeBuilder.labelBinding(end); + return new CompileVisitResult(currentExpectedType); + } + + @Override + public CompileVisitResult visitIdentifier(final @NotNull IdentifierExpression expression) { + final String name = expression.name(); + final Integer paramIndex = argumentParameterIndexes.get(name); + if (paramIndex == null) { + throw new IllegalStateException("Unknown variable: " + name); + } + + final Parameter[] parameters = method.getParameters(); + final Parameter parameter = parameters[paramIndex]; + int loadIndex = 1; + for (int i = 0; i < paramIndex; i++) { + final Parameter param = parameters[i]; + final Class paramType = param.getType(); + if (paramType.equals(double.class) || paramType.equals(long.class)) { + loadIndex += 2; + } else { + loadIndex += 1; + } + } + + final ClassDesc parameterType = classDescOf(parameter.getType()); + + ClassFileUtil.addLoad(codeBuilder, loadIndex, parameterType); + + if (expectedType == null) { + // we are free to use anything, no need to cast + return new CompileVisitResult(parameterType); + } + + // convert to the expected type + ClassFileUtil.addCast(codeBuilder, parameterType, expectedType); + return new CompileVisitResult(expectedType); + } + + @Override + public CompileVisitResult visitAccess(final @NotNull AccessExpression expression) { + final Expression objectExpr = expression.object(); + final String property = expression.property(); + + if (objectExpr instanceof IdentifierExpression) { + final String name = ((IdentifierExpression) objectExpr).name(); + if (name.equals("temp") || name.equals("t")) { + // temps are locals + final Integer localIndex = localsByName.get(property); + if (localIndex == null) { + codeBuilder.fconst_0(); + } else { + codeBuilder.fload(localIndex); + } + return CompileVisitResult.FLOAT; + } + } + + final Value objectValue = objectExpr.visit(this.scopeResolver); + + if (objectValue instanceof ObjectValue) { + final ObjectValue actualObjectValue = (ObjectValue) objectValue; + if (actualObjectValue instanceof JavaObjectBinding) { + final JavaFieldBinding javaFieldBinding = ((JavaObjectBinding) actualObjectValue).getField(property); + if (javaFieldBinding == null) { + // push zero only + codeBuilder.fconst_0(); + } else if (javaFieldBinding.constant()) { + // inline const + codeBuilder.loadConstant(javaFieldBinding.get().getAsNumber()); + } else { + final Field field = javaFieldBinding.field(); + if (Modifier.isStatic(field.getModifiers())) { + codeBuilder.getstatic( + classDescOf(field.getDeclaringClass()), + field.getName(), + classDescOf(field.getType()) + ); + } + } + } + } + + return null; + } + + @Override + public CompileVisitResult visitCall(final @NotNull CallExpression expression) { + final ClassDesc targetType = this.expectedType; + final Expression functionExpr = expression.function(); + + final Value functionValue = functionExpr.visit(this.scopeResolver); + + if (!(functionValue instanceof Function)) { + // not a function, just add 0 + codeBuilder.fconst_0(); + return CompileVisitResult.FLOAT; + } + + final Function function = (Function) functionValue; + + if (function instanceof JavaFunction) { + // we can compile to directly call this function (Java Method) + final JavaFunction javaFunction = (JavaFunction) function; + final Method nativeMethod = javaFunction.method(); + final Parameter[] parameters = nativeMethod.getParameters(); + final List arguments = expression.arguments(); + + final ClassDesc[] ctParameters = new ClassDesc[parameters.length]; + for (int i = 0; i < parameters.length; i++) { + ctParameters[i] = classDescOf(parameters[i].getType()); + } + + final boolean isStatic = Modifier.isStatic(nativeMethod.getModifiers()); + + // load instance + if (!isStatic) { + final Object object = javaFunction.object(); + final String fieldName = object.getClass().getSimpleName().toLowerCase(Locale.ROOT) + Integer.toHexString(object.hashCode()); + requirements.put(fieldName, object); + + final ClassDesc requirementType = classDescOf(object.getClass()); + + // we must load object + codeBuilder.aload(0); + codeBuilder.getfield(functionCompileState.classDesc(), fieldName, requirementType); + } + + // load arguments + final Iterator it = arguments.iterator(); + for (int i = 0; i < parameters.length; i++) { + final Parameter parameter = parameters[i]; + final ClassDesc paramType = ctParameters[i]; + + if (parameter.isAnnotationPresent(Entity.class)) { + Object entity = functionCompileState.compiler().entity(); + if (entity == null || !parameter.getType().isInstance(entity)) { + // load null + addConstZero(codeBuilder, paramType); + } else { + // add entity requirement + requirements.put("__entity__", entity); + + // load entity requirement (field) + codeBuilder.aload(0); // load this + codeBuilder.getfield( + functionCompileState.classDesc(), + "__entity__", + paramType + ); + } + continue; + } + + if (!it.hasNext()) { + addConstZero(codeBuilder, paramType); + continue; + } + + // Set the expected type, then load + this.expectedType = paramType; + it.next().visit(this); + } + + final ClassDesc declaringClassDesc = classDescOf(nativeMethod.getDeclaringClass()); + final ClassDesc returnTypeDesc = classDescOf(nativeMethod.getReturnType()); + final MethodTypeDesc methodTypeDesc = MethodTypeDesc.of(returnTypeDesc, ctParameters); + + if (isStatic) { + // invoke static + codeBuilder.invokestatic(declaringClassDesc, nativeMethod.getName(), methodTypeDesc); + } else { + codeBuilder.invokevirtual(declaringClassDesc, nativeMethod.getName(), methodTypeDesc); + } + + if (nativeMethod.getReturnType() == void.class) { + if (targetType != null && !targetType.equals(CD_void)) { + addConstZero(codeBuilder, targetType); + return new CompileVisitResult(targetType); + } + return CompileVisitResult.VOID; + } else { + if (targetType != null && !returnTypeDesc.equals(targetType)) { + ClassFileUtil.addCast(codeBuilder, returnTypeDesc, targetType); + return new CompileVisitResult(targetType); + } + return new CompileVisitResult(returnTypeDesc); + } + } else { + throw new UnsupportedOperationException("Not supporting non-Java functions yet"); + } + } + + @Override + public CompileVisitResult visit(final @NotNull Expression expression) { + throw new UnsupportedOperationException("Unsupported expression type: " + expression); + } + + private void addConst0(final ClassDesc type) { + if (type == null || type.equals(CD_float)) { + codeBuilder.fconst_0(); + } else if (type.equals(CD_double)) { + codeBuilder.dconst_0(); + } else if (type.equals(CD_long)) { + codeBuilder.lconst_0(); + } else { + codeBuilder.iconst_0(); + } + } + + private void addConst1(final ClassDesc type) { + if (type == null || type.equals(CD_float)) { + codeBuilder.fconst_1(); + } else if (type.equals(CD_double)) { + codeBuilder.dconst_1(); + } else if (type.equals(CD_long)) { + codeBuilder.lconst_1(); + } else { + codeBuilder.iconst_1(); + } + } +} diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java index 6a4104a..b854b1b 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.compiled; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.compiled; import team.unnamed.mocha.runtime.MolangCompiler; diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/Named.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/Named.java index b548d6d..2ad6d11 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/Named.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/Named.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.compiled; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.compiled; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java index 285975d..8b81390 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java @@ -1,4 +1,4 @@ -@ReflectionSupport(ReflectionSupport.Level.FULL) -package team.unnamed.mocha.runtime.compiled; - +@ReflectionSupport(ReflectionSupport.Level.FULL) +package team.unnamed.mocha.runtime.compiled; + import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java b/runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java index 5337f70..3a7ecd8 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java @@ -1,56 +1,56 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha; - -import org.jetbrains.annotations.NotNull; - -import java.util.function.UnaryOperator; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public final class MochaAssertions { - private MochaAssertions() { - throw new UnsupportedOperationException("This class cannot be instantiated"); - } - - public static void assertEvaluates(final double expected, final @NotNull String expr, final @NotNull UnaryOperator> configurer) { - MochaEngine engine = MochaEngine.createStandard(); - engine = configurer.apply(engine); - final double result = engine.interpreter().eval(expr); - assertEquals(expected, result, 0.0001, () -> "Expression: '" + expr + "' evaluated to " + result + ", expected " + expected); - } - - public static void assertEvaluates(final double expected, final @NotNull String expr) { - assertEvaluates(expected, expr, engine -> engine); - } - - public static void assertEvaluatesAndCompiles(final double expected, final @NotNull String expr) { - final MochaEngine engine = MochaEngine.createStandard(); - final double result = engine.interpreter().eval(expr); - assertEquals(expected, result, 0.0001, () -> "(Interpreted) expression: '" + expr + "' evaluated to " + result + ", expected " + expected); - - final double compiledResult = engine.compiler().compile(expr).evaluate(); - assertEquals(expected, compiledResult, 0.0001, () -> "(Compiled) expression: '" + expr + "' evaluated to " + compiledResult + ", expected " + expected); - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha; + +import org.jetbrains.annotations.NotNull; + +import java.util.function.UnaryOperator; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public final class MochaAssertions { + private MochaAssertions() { + throw new UnsupportedOperationException("This class cannot be instantiated"); + } + + public static void assertEvaluates(final double expected, final @NotNull String expr, final @NotNull UnaryOperator> configurer) { + MochaEngine engine = MochaEngine.createStandard(); + engine = configurer.apply(engine); + final double result = engine.interpreter().eval(expr); + assertEquals(expected, result, 0.0001, () -> "Expression: '" + expr + "' evaluated to " + result + ", expected " + expected); + } + + public static void assertEvaluates(final double expected, final @NotNull String expr) { + assertEvaluates(expected, expr, engine -> engine); + } + + public static void assertEvaluatesAndCompiles(final double expected, final @NotNull String expr) { + final MochaEngine engine = MochaEngine.createStandard(); + final double result = engine.interpreter().eval(expr); + assertEquals(expected, result, 0.0001, () -> "(Interpreted) expression: '" + expr + "' evaluated to " + result + ", expected " + expected); + + final double compiledResult = engine.compiler().compile(expr).evaluate(); + assertEquals(expected, compiledResult, 0.0001, () -> "(Compiled) expression: '" + expr + "' evaluated to " + compiledResult + ", expected " + expected); + } +} diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java index f63c4b4..7af0476 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java @@ -1,59 +1,59 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; - -import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class BreakContinueTest { - @Test - void test_break() { - final float value = MochaEngine.createStandard().interpreter().eval(String.join("\n", - "t.i = 0;", - "loop(10, {", - " t.i = t.i + 1;", - " (t.i >= 5) ? break;", - "});", - "return t.i;" - )); - assertEquals(5.0F, value); - } - - @Test - void test_continue() { - final float value = MochaEngine.createStandard().interpreter().eval( - "t.i = 0;" + - "t.sum = 0;" + - "loop(20, {" + - "t.i = t.i + 1;" + - "((t.i < 8) || (t.i > 17)) ? continue;" + - "t.sum = t.sum + t.i;" + - "});" + - "return t.sum;" - ); - assertEquals(125.0F, value); - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; + +import org.junit.jupiter.api.Test; +import team.unnamed.mocha.MochaEngine; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class BreakContinueTest { + @Test + void test_break() { + final float value = MochaEngine.createStandard().interpreter().eval(String.join("\n", + "t.i = 0;", + "loop(10, {", + " t.i = t.i + 1;", + " (t.i >= 5) ? break;", + "});", + "return t.i;" + )); + assertEquals(5.0F, value); + } + + @Test + void test_continue() { + final float value = MochaEngine.createStandard().interpreter().eval( + "t.i = 0;" + + "t.sum = 0;" + + "loop(20, {" + + "t.i = t.i + 1;" + + "((t.i < 8) || (t.i > 17)) ? continue;" + + "t.sum = t.sum + t.i;" + + "});" + + "return t.sum;" + ); + assertEquals(125.0F, value); + } +} diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CompareTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CompareTest.java index 01af59b..c19c72e 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CompareTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CompareTest.java @@ -1,118 +1,118 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -/** - * Compares the results of this library with the - * results of other libraries - */ -public class CompareTest { - - private static final MochaEngine ENGINE = MochaEngine.createStandard(); - - //#region Helper code - private static BufferedReader createResourceReader(String name) { - InputStream stream = CompareTest.class - .getClassLoader() - .getResourceAsStream(name); - if (stream == null) { - throw new IllegalStateException("Resource not found: " + name); - } - return new BufferedReader(new InputStreamReader(stream)); - } - - private static String nextNonEmpty(BufferedReader reader) throws IOException { - String value; - do { - value = reader.readLine(); - if (value == null) { - break; - } else { - value = value.trim(); - } - } while (value.isEmpty() || value.charAt(0) == '#'); - return value; - } - - private static void compare(String expectationsName, String sourceName) throws IOException { - try (BufferedReader source = createResourceReader(sourceName)) { - try (BufferedReader expectations = createResourceReader(expectationsName)) { - while (true) { - String expression = nextNonEmpty(source); - String expected = nextNonEmpty(expectations); - - if (expression == null || expected == null) { - // end reached - break; - } - - float expectedValue = Float.parseFloat(expected); - - // eval expression - final float result = ENGINE.interpreter().eval(expression); - Assertions.assertEquals( - expectedValue, - result, - 0.001f, - () -> "Incorrect result for INTERPRETED expression: " + expression - ); - - // compile and eval expression - try { - final float compileResult = ENGINE.compiler().compile(expression).evaluate(); - Assertions.assertEquals( - expectedValue, - compileResult, - 0.001f, - () -> "Incorrect result for COMPILED expression: " + expression - ); - } catch (Throwable e) { - throw new IllegalStateException("Error while compiling expression: " + expression, e); - } - } - } - } - } - - /** - * Compares this library results with MolangJS - * of JannisX11 - * https://github.com/JannisX11/MolangJS - */ - @Test - public void compare_with_molangjs() throws IOException { - compare("expectations.txt", "tests.txt"); - } - //#endregion - -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import team.unnamed.mocha.MochaEngine; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * Compares the results of this library with the + * results of other libraries + */ +public class CompareTest { + + private static final MochaEngine ENGINE = MochaEngine.createStandard(); + + //#region Helper code + private static BufferedReader createResourceReader(String name) { + InputStream stream = CompareTest.class + .getClassLoader() + .getResourceAsStream(name); + if (stream == null) { + throw new IllegalStateException("Resource not found: " + name); + } + return new BufferedReader(new InputStreamReader(stream)); + } + + private static String nextNonEmpty(BufferedReader reader) throws IOException { + String value; + do { + value = reader.readLine(); + if (value == null) { + break; + } else { + value = value.trim(); + } + } while (value.isEmpty() || value.charAt(0) == '#'); + return value; + } + + private static void compare(String expectationsName, String sourceName) throws IOException { + try (BufferedReader source = createResourceReader(sourceName)) { + try (BufferedReader expectations = createResourceReader(expectationsName)) { + while (true) { + String expression = nextNonEmpty(source); + String expected = nextNonEmpty(expectations); + + if (expression == null || expected == null) { + // end reached + break; + } + + float expectedValue = Float.parseFloat(expected); + + // eval expression + final float result = ENGINE.interpreter().eval(expression); + Assertions.assertEquals( + expectedValue, + result, + 0.001f, + () -> "Incorrect result for INTERPRETED expression: " + expression + ); + + // compile and eval expression + try { + final float compileResult = ENGINE.compiler().compile(expression).evaluate(); + Assertions.assertEquals( + expectedValue, + compileResult, + 0.001f, + () -> "Incorrect result for COMPILED expression: " + expression + ); + } catch (Throwable e) { + throw new IllegalStateException("Error while compiling expression: " + expression, e); + } + } + } + } + } + + /** + * Compares this library results with MolangJS + * of JannisX11 + * https://github.com/JannisX11/MolangJS + */ + @Test + public void compare_with_molangjs() throws IOException { + compare("expectations.txt", "tests.txt"); + } + //#endregion + +} diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java index eda644b..042903e 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.junit.jupiter.api.Test; import team.unnamed.mocha.MochaEngine; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java index 6c074b8..e3b2470 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java index 84fbefc..fcddaaa 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.junit.jupiter.api.Test; import team.unnamed.mocha.MochaEngine; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java index 7ef7416..586bfae 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.junit.jupiter.api.Test; import team.unnamed.mocha.MochaEngine; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java index 0e6a135..6894bb8 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java index ff1ccee..b5864c2 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java @@ -1,92 +1,92 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.arrow; - -import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.binding.Binding; -import team.unnamed.mocha.runtime.binding.Entity; -import team.unnamed.mocha.runtime.value.JavaValue; - -import java.util.ArrayList; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class ArrowOperatorTest { - @Test - void test() { - final World world = new World(); - final Player self = new Player(world, 8, "Steve"); - new Player(world, 9, "Pig"); - new Player(world, 15, "Chicken"); - new Player(world, 0, "Zombie"); - - final MochaEngine engine = MochaEngine.createStandard(self); - engine.interpreter().bind(QueryImpl.class); - engine.scope().set("self", new JavaValue(self)); - - final float result = engine.interpreter().eval( - "v.result = 0;\n" - + "for_each(t.nearby, self->q.get_nearby_entities(5), {\n" - + " v.result = v.result + t.nearby->q.get_location();\n" - + "});\n" - + "return v.result;" - ); - assertEquals(17F, result); - - - final float result2 = engine.interpreter().eval( - "v.result = 0;\n" - + "for_each(t.nearby, self->q.get_nearby_entities(500), {\n" // Same code but 500 instead of 5 - + " v.result = v.result + t.nearby->q.get_location();\n" - + "});\n" - + "return v.result;" - ); - assertEquals(32F, result2); - } - - @Binding({"query", "q"}) - public static final class QueryImpl { - @Binding("get_location") - public static double getLocation(final @Entity Player player) { - return player.location; - } - - @Binding("get_nearby_entities") - public static Player[] getNearbyEntities(final @Entity Player player, final double distance) { - final int from = (int) Math.max(player.location - distance, 0); - final int to = (int) Math.min(player.location + distance, player.world.entities.length); - - List found = new ArrayList<>(); - for (int i = from; i < to; i++) { - final Player nearby = player.world.entities[i]; - if (nearby != null) { - found.add(nearby); - } - } - return found.toArray(Player[]::new); - } - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.arrow; + +import org.junit.jupiter.api.Test; +import team.unnamed.mocha.MochaEngine; +import team.unnamed.mocha.runtime.binding.Binding; +import team.unnamed.mocha.runtime.binding.Entity; +import team.unnamed.mocha.runtime.value.JavaValue; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ArrowOperatorTest { + @Test + void test() { + final World world = new World(); + final Player self = new Player(world, 8, "Steve"); + new Player(world, 9, "Pig"); + new Player(world, 15, "Chicken"); + new Player(world, 0, "Zombie"); + + final MochaEngine engine = MochaEngine.createStandard(self); + engine.interpreter().bind(QueryImpl.class); + engine.scope().set("self", new JavaValue(self)); + + final float result = engine.interpreter().eval( + "v.result = 0;\n" + + "for_each(t.nearby, self->q.get_nearby_entities(5), {\n" + + " v.result = v.result + t.nearby->q.get_location();\n" + + "});\n" + + "return v.result;" + ); + assertEquals(17F, result); + + + final float result2 = engine.interpreter().eval( + "v.result = 0;\n" + + "for_each(t.nearby, self->q.get_nearby_entities(500), {\n" // Same code but 500 instead of 5 + + " v.result = v.result + t.nearby->q.get_location();\n" + + "});\n" + + "return v.result;" + ); + assertEquals(32F, result2); + } + + @Binding({"query", "q"}) + public static final class QueryImpl { + @Binding("get_location") + public static double getLocation(final @Entity Player player) { + return player.location; + } + + @Binding("get_nearby_entities") + public static Player[] getNearbyEntities(final @Entity Player player, final double distance) { + final int from = (int) Math.max(player.location - distance, 0); + final int to = (int) Math.min(player.location + distance, player.world.entities.length); + + List found = new ArrayList<>(); + for (int i = from; i < to; i++) { + final Player nearby = player.world.entities[i]; + if (nearby != null) { + found.add(nearby); + } + } + return found.toArray(Player[]::new); + } + } +} diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/Player.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/Player.java index c912243..ffbdb57 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/Player.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/Player.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.arrow; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.arrow; class Player { World world; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/World.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/World.java index 602be86..988bd86 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/World.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/World.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.arrow; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.arrow; class World { // 1-dimensional world Player[] entities = new Player[64]; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java index 1e4d517..03b2bc8 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.jvm; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.jvm; import org.junit.jupiter.api.Test; import team.unnamed.mocha.MochaEngine; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java index f158713..cccb96a 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java +++ b/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java @@ -1,64 +1,64 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.jvm; - -import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; -import team.unnamed.mocha.runtime.compiled.Named; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class MathCompiledRuntimeTest { - @Test - void test() { - final MochaEngine engine = MochaEngine.createStandard(); - { - // 0: dload_1 - // 1: invokestatic - // 4: dreturn - final MathFunction cos = engine.compiler().compile("math.cos(x)", MathFunction.class); - assertEquals(1F, cos.apply(0), 0.0001); - assertEquals(4F / 5D, cos.apply(37), 0.01); - assertEquals(3F / 5D, cos.apply(53), 0.01); - assertEquals(0F, cos.apply(90), 0.0001); - assertEquals(-1F, cos.apply(180), 0.0001); - } - { - // 0: dload_1 - // 1: invokestatic - // 4: l2d - // 5: dreturn - final MathFunction round = engine.compiler().compile("math.round(x)", MathFunction.class); - assertEquals(5.0F, round.apply(5.4F)); - assertEquals(6.0F, round.apply(5.5F)); - assertEquals(6.0F, round.apply(5.6F)); - assertEquals(-5.0F, round.apply(-5.4F)); - } - } - - public interface MathFunction extends MochaCompiledFunction { - float apply(@Named("x") float x); - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.jvm; + +import org.junit.jupiter.api.Test; +import team.unnamed.mocha.MochaEngine; +import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; +import team.unnamed.mocha.runtime.compiled.Named; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class MathCompiledRuntimeTest { + @Test + void test() { + final MochaEngine engine = MochaEngine.createStandard(); + { + // 0: dload_1 + // 1: invokestatic + // 4: dreturn + final MathFunction cos = engine.compiler().compile("math.cos(x)", MathFunction.class); + assertEquals(1F, cos.apply(0), 0.0001); + assertEquals(4F / 5D, cos.apply(37), 0.01); + assertEquals(3F / 5D, cos.apply(53), 0.01); + assertEquals(0F, cos.apply(90), 0.0001); + assertEquals(-1F, cos.apply(180), 0.0001); + } + { + // 0: dload_1 + // 1: invokestatic + // 4: l2d + // 5: dreturn + final MathFunction round = engine.compiler().compile("math.round(x)", MathFunction.class); + assertEquals(5.0F, round.apply(5.4F)); + assertEquals(6.0F, round.apply(5.5F)); + assertEquals(6.0F, round.apply(5.6F)); + assertEquals(-5.0F, round.apply(-5.4F)); + } + } + + public interface MathFunction extends MochaCompiledFunction { + float apply(@Named("x") float x); + } +} diff --git a/runtime/build.gradle b/runtime/build.gradle index 7bf1905..1f1b554 100644 --- a/runtime/build.gradle +++ b/runtime/build.gradle @@ -1,3 +1,3 @@ -dependencies { - api project(":parser") -} +dependencies { + api project(":parser") +} diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java b/runtime/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java index 847ddba..22a0963 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java b/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java index 95f2bb8..32f33c0 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.jetbrains.annotations.NotNull; import team.unnamed.mocha.parser.ast.BinaryExpression; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java b/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java index c01a920..06dfe9d 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java @@ -1,478 +1,478 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; - -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.ast.*; -import team.unnamed.mocha.runtime.binding.JavaFunction; -import team.unnamed.mocha.runtime.value.*; - -import java.util.Arrays; -import java.util.List; - -import static java.util.Objects.requireNonNull; - -@ApiStatus.Internal -public final class ExpressionInterpreter implements ExpressionVisitor, ExecutionContext { - private static final List BINARY_EVALUATORS = Arrays.asList( - bool((a, b) -> a.eval() && b.eval()), - bool((a, b) -> a.eval() || b.eval()), - compare((a, b) -> a.eval() < b.eval()), - compare((a, b) -> a.eval() <= b.eval()), - compare((a, b) -> a.eval() > b.eval()), - compare((a, b) -> a.eval() >= b.eval()), - (evaluator, a, b) -> { - final Value aVal = a.visit(evaluator); - final Value bVal = b.visit(evaluator); - // string concatenation is not supported in molang - // if (aVal.isString() || bVal.isString()) { - // return StringValue.of(aVal.getAsString() + bVal.getAsString()); - // } else { - return NumberValue.of(aVal.getAsNumber() + bVal.getAsNumber()); - // } - }, - arithmetic((a, b) -> a.eval() - b.eval()), - arithmetic((a, b) -> a.eval() * b.eval()), - arithmetic((a, b) -> { - // Molang allows division by zero, - // which is always equal to 0 - final float dividend = a.eval(); - final float divisor = b.eval(); - if (divisor == 0) return 0; - else return dividend / divisor; - }), - (evaluator, a, b) -> { // arrow - final Value val = a.visit(evaluator); - if (!(val instanceof JavaValue)) { - return NumberValue.zero(); - } else { - return b.visit(evaluator.createChild(((JavaValue) val).value())); - } - }, - (evaluator, a, b) -> { // null coalesce - final Value val = a.visit(evaluator); - if (val.getAsBoolean()) { - return val; - } else { - return b.visit(evaluator); - } - }, - (evaluator, a, b) -> { // assignation - final Value val = b.visit(evaluator); - // we can only assign to values that are accessed - // like: - // temp.x = 1 - // t.location.world = 'world' - // but not: - // x = 1 - // i = 2 - if (a instanceof AccessExpression) { - final AccessExpression access = (AccessExpression) a; - final Value objectValue = access.object().visit(evaluator); - if (objectValue instanceof MutableObjectBinding) { - ((MutableObjectBinding) objectValue).set(access.property(), val); - } - } - return val; - }, - (evaluator, a, b) -> { // conditional - final Value conditionValue = a.visit(evaluator); - if (conditionValue.getAsBoolean()) { - final Value predicateVal = b.visit(evaluator); - if (predicateVal instanceof Function) { - return Value.of(((Function) predicateVal).evaluate(evaluator)); - } else { - return predicateVal; - } - } - return NumberValue.zero(); - }, - arithmetic((a, b) -> ((a.eval() == b.eval()) ? 1.0F : 0.0F)), // eq - arithmetic((a, b) -> ((a.eval() != b.eval()) ? 1.0F : 0.0F)) // neq - ); - - private final T entity; - private final Scope scope; - private @Nullable Object flag; - private @Nullable Value returnValue; - - private boolean warnOnReflectiveFunctionUsage; - - public ExpressionInterpreter(final @Nullable T entity, final @NotNull Scope scope) { - this.entity = entity; - this.scope = requireNonNull(scope, "scope"); - } - - private static Evaluator bool(BooleanOperator op) { - return (evaluator, a, b) -> Value.of(op.operate( - () -> a.visit(evaluator).getAsBoolean(), - () -> b.visit(evaluator).getAsBoolean() - )); - } - - private static Evaluator compare(Comparator comp) { - return (evaluator, a, b) -> Value.of(comp.compare( - () -> a.visit(evaluator).getAsNumber(), - () -> b.visit(evaluator).getAsNumber() - )); - } - - private static Evaluator arithmetic(ArithmeticOperator op) { - return (evaluator, a, b) -> NumberValue.of(op.operate( - () -> a.visit(evaluator).getAsNumber(), - () -> b.visit(evaluator).getAsNumber() - )); - } - - public void warnOnReflectiveFunctionUsage(final boolean warnOnReflectiveFunctionUsage) { - this.warnOnReflectiveFunctionUsage = warnOnReflectiveFunctionUsage; - } - - @Override - public @Nullable Object flag() { - return flag; - } - - @Override - public void flag(final @Nullable Object flag) { - this.flag = flag; - } - - @Override - public T entity() { - return entity; - } - - @Override - public @NotNull Value eval(final @NotNull Expression expression) { - return expression.visit(this); - } - - public @NotNull ExpressionInterpreter createChild(final @Nullable R entity) { - return new ExpressionInterpreter<>(entity, this.scope); - } - - public @NotNull ExpressionInterpreter createChild() { - // Note that it will have its own returnValue, but same bindings - // (Should we create new bindings?) - return new ExpressionInterpreter<>(this.entity, this.scope); - } - - public @NotNull Scope bindings() { - return scope; - } - - public @Nullable Value popReturnValue() { - final Value val = this.returnValue; - this.returnValue = null; - return val; - } - - @Override - public @NotNull Value visitArrayAccess(final @NotNull ArrayAccessExpression expression) { - final Value array = expression.array().visit(this); - final Value index = expression.index().visit(this); - if (!(array instanceof ArrayValue)) { - return Value.nil(); - } else { - final Value[] values = ((ArrayValue) array).values(); - final int validIndex = Math.max(0, (int) index.getAsNumber()) % values.length; - return values[validIndex]; - } - } - - @Override - public @NotNull Value visitAccess(final @NotNull AccessExpression expression) { - final Value objectValue = expression.object().visit(this); - if (objectValue instanceof ObjectValue) { - return ((ObjectValue) objectValue).get(expression.property()); - } - return NumberValue.zero(); - } - - @Override - public @NotNull Value visitCall(final @NotNull CallExpression expression) { - final List argumentsExpressions = expression.arguments(); - final Function.Argument[] arguments = new Function.Argument[argumentsExpressions.size()]; - for (int i = 0; i < argumentsExpressions.size(); i++) { - arguments[i] = new FunctionArgumentImpl(argumentsExpressions.get(i)); - } - final Function.Arguments args = new FunctionArguments(arguments); - - final Expression functionExpr = expression.function(); - if (functionExpr instanceof IdentifierExpression) { - final String identifierName = ((IdentifierExpression) functionExpr).name(); - if ("loop".equals(identifierName)) { - // loop built-in function - // Parameters: - // - float: How many times should we loop - // - CallableBinding: The looped expressions - int n = Math.round(args.next().eval().getAsNumber()); - Value expr = args.next().eval(); - - if (expr instanceof Function) { - final Function callable = (Function) expr; - for (int i = 0; i < n; i++) { - final ExpressionInterpreter evaluatorThisCall = createChild(); - callable.evaluate(evaluatorThisCall); - if (evaluatorThisCall.flag() == StatementExpression.Op.BREAK) { - break; - } - // (not necessary, callable already exits when returnValue - // is set to any non-null value) - // if (value == StatementExpression.Op.CONTINUE) continue; - } - } - return NumberValue.zero(); - } else if ("for_each".equals(identifierName)) { - // for each built-in function - // Parameters: - // - any: Variable - // - array: Any array - // - CallableBinding: The looped expressions - final Expression variableExpr = args.next().expression(); - if (!(variableExpr instanceof AccessExpression)) { - // first argument must be an access expression, - // e.g. 'variable.test', 'v.pig', 't.entity' or - // 't.entity.location.world' - return NumberValue.zero(); - } - final AccessExpression variableAccess = (AccessExpression) variableExpr; - final Expression objectExpr = variableAccess.object(); - final String propertyName = variableAccess.property(); - - final Value array = args.next().eval(); - final Iterable arrayIterable; - if (array instanceof ArrayValue) { - arrayIterable = Arrays.asList(((ArrayValue) array).values()); - } else { - // second argument must be an array or iterable - return NumberValue.zero(); - } - - final Value expr = args.next().eval(); - - if (expr instanceof Function) { - final Function callable = (Function) expr; - for (final Value val : arrayIterable) { - // set 'val' as current value - // eval (objectExpr.propertyName = val) - final Value evaluatedObjectValue = this.eval(objectExpr); - if (evaluatedObjectValue instanceof MutableObjectBinding) { - ((MutableObjectBinding) evaluatedObjectValue).set(propertyName, val); - } - final Object returnValue = callable.evaluate(this); - - if (returnValue == StatementExpression.Op.BREAK) { - break; - } - } - } - return NumberValue.zero(); - } - } - - final Value function = functionExpr.visit(this); - if (!(function instanceof Function)) { - return Value.nil(); - } - - if (warnOnReflectiveFunctionUsage && function instanceof JavaFunction) { - final JavaFunction javaFunction = (JavaFunction) function; - System.err.println("Warning: Reflective function usage detected for method: " + javaFunction.method()); - } - - return ((Function) function).evaluate(this, args); - } - - @Override - public @NotNull Value visitFloat(final @NotNull FloatExpression expression) { - return NumberValue.of(expression.value()); - } - - @Override - public @NotNull Value visitExecutionScope(final @NotNull ExecutionScopeExpression executionScope) { - List expressions = executionScope.expressions(); - return (Function) (context, arguments) -> { - for (Expression expression : expressions) { - // eval expression, ignore result - context.eval(expression); - - // check for return values - if (context.flag() != null) { - break; - } - } - return NumberValue.zero(); - }; - } - - @Override - public @NotNull Value visitIdentifier(final @NotNull IdentifierExpression expression) { - return scope.get(expression.name()); - } - - @Override - public @NotNull Value visitBinary(@NotNull BinaryExpression expression) { - return BINARY_EVALUATORS.get(expression.op().ordinal()).eval( - this, - expression.left(), - expression.right() - ); - } - - @Override - public @NotNull Value visitUnary(final @NotNull UnaryExpression expression) { - final Value value = expression.expression().visit(this); - switch (expression.op()) { - case LOGICAL_NEGATION: - return Value.of(!value.getAsBoolean()); - case ARITHMETICAL_NEGATION: - return NumberValue.of(-value.getAsNumber()); - case RETURN: { - this.returnValue = value; - return NumberValue.zero(); - } - default: - throw new IllegalStateException("Unknown operation"); - } - } - - @Override - public @NotNull Value visitStatement(final @NotNull StatementExpression expression) { - switch (expression.op()) { - case BREAK: { - this.flag = StatementExpression.Op.BREAK; - break; - } - case CONTINUE: { - this.flag = StatementExpression.Op.CONTINUE; - break; - } - } - return NumberValue.zero(); - } - - @Override - public @NotNull Value visitString(final @NotNull StringExpression expression) { - return StringValue.of(expression.value()); - } - - @Override - public @NotNull Value visitTernaryConditional(@NotNull TernaryConditionalExpression expression) { - final Value conditionResult = expression.condition().visit(this); - return conditionResult.getAsBoolean() - ? expression.trueExpression().visit(this) - : expression.falseExpression().visit(this); - } - - @Override - public Value visit(final @NotNull Expression expression) { - throw new UnsupportedOperationException("Unsupported expression type: " + expression); - } - - private interface Evaluator { - @NotNull Value eval(ExpressionInterpreter evaluator, Expression a, Expression b); - } - - private interface BooleanOperator { - boolean operate(LazyEvaluableBoolean a, LazyEvaluableBoolean b); - } - - interface LazyEvaluableBoolean { - boolean eval(); - } - - interface LazyEvaluableFloat { - float eval(); - } - - private interface Comparator { - boolean compare(LazyEvaluableFloat a, LazyEvaluableFloat b); - - } - - private interface ArithmeticOperator { - float operate(LazyEvaluableFloat a, LazyEvaluableFloat b); - } - - public static class FunctionArguments implements Function.Arguments { - public static final Function.Arguments EMPTY = new FunctionArguments(new Function.Argument[0]); - - private final Function.Argument[] arguments; - private int next; - - FunctionArguments(final @NotNull Function.Argument @NotNull [] arguments) { - this.arguments = requireNonNull(arguments, "arguments"); - } - - @Override - public Function.@NotNull Argument next() { - if (next < arguments.length) { - return arguments[next++]; - } else { - return EmptyFunctionArgument.EMPTY; - } - } - - @Override - public int length() { - return arguments.length; - } - } - - private static class EmptyFunctionArgument implements Function.Argument { - static final Function.Argument EMPTY = new EmptyFunctionArgument(); - - @Override - public @Nullable Expression expression() { - return null; - } - - @Override - public @Nullable Value eval() { - return NumberValue.zero(); - } - } - - private class FunctionArgumentImpl implements Function.Argument { - private final Expression expression; - - FunctionArgumentImpl(final @NotNull Expression expression) { - this.expression = expression; - } - - @Override - public @NotNull Expression expression() { - return expression; - } - - @Override - public @Nullable Value eval() { - return expression.visit(ExpressionInterpreter.this); - } - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import team.unnamed.mocha.parser.ast.*; +import team.unnamed.mocha.runtime.binding.JavaFunction; +import team.unnamed.mocha.runtime.value.*; + +import java.util.Arrays; +import java.util.List; + +import static java.util.Objects.requireNonNull; + +@ApiStatus.Internal +public final class ExpressionInterpreter implements ExpressionVisitor, ExecutionContext { + private static final List BINARY_EVALUATORS = Arrays.asList( + bool((a, b) -> a.eval() && b.eval()), + bool((a, b) -> a.eval() || b.eval()), + compare((a, b) -> a.eval() < b.eval()), + compare((a, b) -> a.eval() <= b.eval()), + compare((a, b) -> a.eval() > b.eval()), + compare((a, b) -> a.eval() >= b.eval()), + (evaluator, a, b) -> { + final Value aVal = a.visit(evaluator); + final Value bVal = b.visit(evaluator); + // string concatenation is not supported in molang + // if (aVal.isString() || bVal.isString()) { + // return StringValue.of(aVal.getAsString() + bVal.getAsString()); + // } else { + return NumberValue.of(aVal.getAsNumber() + bVal.getAsNumber()); + // } + }, + arithmetic((a, b) -> a.eval() - b.eval()), + arithmetic((a, b) -> a.eval() * b.eval()), + arithmetic((a, b) -> { + // Molang allows division by zero, + // which is always equal to 0 + final float dividend = a.eval(); + final float divisor = b.eval(); + if (divisor == 0) return 0; + else return dividend / divisor; + }), + (evaluator, a, b) -> { // arrow + final Value val = a.visit(evaluator); + if (!(val instanceof JavaValue)) { + return NumberValue.zero(); + } else { + return b.visit(evaluator.createChild(((JavaValue) val).value())); + } + }, + (evaluator, a, b) -> { // null coalesce + final Value val = a.visit(evaluator); + if (val.getAsBoolean()) { + return val; + } else { + return b.visit(evaluator); + } + }, + (evaluator, a, b) -> { // assignation + final Value val = b.visit(evaluator); + // we can only assign to values that are accessed + // like: + // temp.x = 1 + // t.location.world = 'world' + // but not: + // x = 1 + // i = 2 + if (a instanceof AccessExpression) { + final AccessExpression access = (AccessExpression) a; + final Value objectValue = access.object().visit(evaluator); + if (objectValue instanceof MutableObjectBinding) { + ((MutableObjectBinding) objectValue).set(access.property(), val); + } + } + return val; + }, + (evaluator, a, b) -> { // conditional + final Value conditionValue = a.visit(evaluator); + if (conditionValue.getAsBoolean()) { + final Value predicateVal = b.visit(evaluator); + if (predicateVal instanceof Function) { + return Value.of(((Function) predicateVal).evaluate(evaluator)); + } else { + return predicateVal; + } + } + return NumberValue.zero(); + }, + arithmetic((a, b) -> ((a.eval() == b.eval()) ? 1.0F : 0.0F)), // eq + arithmetic((a, b) -> ((a.eval() != b.eval()) ? 1.0F : 0.0F)) // neq + ); + + private final T entity; + private final Scope scope; + private @Nullable Object flag; + private @Nullable Value returnValue; + + private boolean warnOnReflectiveFunctionUsage; + + public ExpressionInterpreter(final @Nullable T entity, final @NotNull Scope scope) { + this.entity = entity; + this.scope = requireNonNull(scope, "scope"); + } + + private static Evaluator bool(BooleanOperator op) { + return (evaluator, a, b) -> Value.of(op.operate( + () -> a.visit(evaluator).getAsBoolean(), + () -> b.visit(evaluator).getAsBoolean() + )); + } + + private static Evaluator compare(Comparator comp) { + return (evaluator, a, b) -> Value.of(comp.compare( + () -> a.visit(evaluator).getAsNumber(), + () -> b.visit(evaluator).getAsNumber() + )); + } + + private static Evaluator arithmetic(ArithmeticOperator op) { + return (evaluator, a, b) -> NumberValue.of(op.operate( + () -> a.visit(evaluator).getAsNumber(), + () -> b.visit(evaluator).getAsNumber() + )); + } + + public void warnOnReflectiveFunctionUsage(final boolean warnOnReflectiveFunctionUsage) { + this.warnOnReflectiveFunctionUsage = warnOnReflectiveFunctionUsage; + } + + @Override + public @Nullable Object flag() { + return flag; + } + + @Override + public void flag(final @Nullable Object flag) { + this.flag = flag; + } + + @Override + public T entity() { + return entity; + } + + @Override + public @NotNull Value eval(final @NotNull Expression expression) { + return expression.visit(this); + } + + public @NotNull ExpressionInterpreter createChild(final @Nullable R entity) { + return new ExpressionInterpreter<>(entity, this.scope); + } + + public @NotNull ExpressionInterpreter createChild() { + // Note that it will have its own returnValue, but same bindings + // (Should we create new bindings?) + return new ExpressionInterpreter<>(this.entity, this.scope); + } + + public @NotNull Scope bindings() { + return scope; + } + + public @Nullable Value popReturnValue() { + final Value val = this.returnValue; + this.returnValue = null; + return val; + } + + @Override + public @NotNull Value visitArrayAccess(final @NotNull ArrayAccessExpression expression) { + final Value array = expression.array().visit(this); + final Value index = expression.index().visit(this); + if (!(array instanceof ArrayValue)) { + return Value.nil(); + } else { + final Value[] values = ((ArrayValue) array).values(); + final int validIndex = Math.max(0, (int) index.getAsNumber()) % values.length; + return values[validIndex]; + } + } + + @Override + public @NotNull Value visitAccess(final @NotNull AccessExpression expression) { + final Value objectValue = expression.object().visit(this); + if (objectValue instanceof ObjectValue) { + return ((ObjectValue) objectValue).get(expression.property()); + } + return NumberValue.zero(); + } + + @Override + public @NotNull Value visitCall(final @NotNull CallExpression expression) { + final List argumentsExpressions = expression.arguments(); + final Function.Argument[] arguments = new Function.Argument[argumentsExpressions.size()]; + for (int i = 0; i < argumentsExpressions.size(); i++) { + arguments[i] = new FunctionArgumentImpl(argumentsExpressions.get(i)); + } + final Function.Arguments args = new FunctionArguments(arguments); + + final Expression functionExpr = expression.function(); + if (functionExpr instanceof IdentifierExpression) { + final String identifierName = ((IdentifierExpression) functionExpr).name(); + if ("loop".equals(identifierName)) { + // loop built-in function + // Parameters: + // - float: How many times should we loop + // - CallableBinding: The looped expressions + int n = Math.round(args.next().eval().getAsNumber()); + Value expr = args.next().eval(); + + if (expr instanceof Function) { + final Function callable = (Function) expr; + for (int i = 0; i < n; i++) { + final ExpressionInterpreter evaluatorThisCall = createChild(); + callable.evaluate(evaluatorThisCall); + if (evaluatorThisCall.flag() == StatementExpression.Op.BREAK) { + break; + } + // (not necessary, callable already exits when returnValue + // is set to any non-null value) + // if (value == StatementExpression.Op.CONTINUE) continue; + } + } + return NumberValue.zero(); + } else if ("for_each".equals(identifierName)) { + // for each built-in function + // Parameters: + // - any: Variable + // - array: Any array + // - CallableBinding: The looped expressions + final Expression variableExpr = args.next().expression(); + if (!(variableExpr instanceof AccessExpression)) { + // first argument must be an access expression, + // e.g. 'variable.test', 'v.pig', 't.entity' or + // 't.entity.location.world' + return NumberValue.zero(); + } + final AccessExpression variableAccess = (AccessExpression) variableExpr; + final Expression objectExpr = variableAccess.object(); + final String propertyName = variableAccess.property(); + + final Value array = args.next().eval(); + final Iterable arrayIterable; + if (array instanceof ArrayValue) { + arrayIterable = Arrays.asList(((ArrayValue) array).values()); + } else { + // second argument must be an array or iterable + return NumberValue.zero(); + } + + final Value expr = args.next().eval(); + + if (expr instanceof Function) { + final Function callable = (Function) expr; + for (final Value val : arrayIterable) { + // set 'val' as current value + // eval (objectExpr.propertyName = val) + final Value evaluatedObjectValue = this.eval(objectExpr); + if (evaluatedObjectValue instanceof MutableObjectBinding) { + ((MutableObjectBinding) evaluatedObjectValue).set(propertyName, val); + } + final Object returnValue = callable.evaluate(this); + + if (returnValue == StatementExpression.Op.BREAK) { + break; + } + } + } + return NumberValue.zero(); + } + } + + final Value function = functionExpr.visit(this); + if (!(function instanceof Function)) { + return Value.nil(); + } + + if (warnOnReflectiveFunctionUsage && function instanceof JavaFunction) { + final JavaFunction javaFunction = (JavaFunction) function; + System.err.println("Warning: Reflective function usage detected for method: " + javaFunction.method()); + } + + return ((Function) function).evaluate(this, args); + } + + @Override + public @NotNull Value visitFloat(final @NotNull FloatExpression expression) { + return NumberValue.of(expression.value()); + } + + @Override + public @NotNull Value visitExecutionScope(final @NotNull ExecutionScopeExpression executionScope) { + List expressions = executionScope.expressions(); + return (Function) (context, arguments) -> { + for (Expression expression : expressions) { + // eval expression, ignore result + context.eval(expression); + + // check for return values + if (context.flag() != null) { + break; + } + } + return NumberValue.zero(); + }; + } + + @Override + public @NotNull Value visitIdentifier(final @NotNull IdentifierExpression expression) { + return scope.get(expression.name()); + } + + @Override + public @NotNull Value visitBinary(@NotNull BinaryExpression expression) { + return BINARY_EVALUATORS.get(expression.op().ordinal()).eval( + this, + expression.left(), + expression.right() + ); + } + + @Override + public @NotNull Value visitUnary(final @NotNull UnaryExpression expression) { + final Value value = expression.expression().visit(this); + switch (expression.op()) { + case LOGICAL_NEGATION: + return Value.of(!value.getAsBoolean()); + case ARITHMETICAL_NEGATION: + return NumberValue.of(-value.getAsNumber()); + case RETURN: { + this.returnValue = value; + return NumberValue.zero(); + } + default: + throw new IllegalStateException("Unknown operation"); + } + } + + @Override + public @NotNull Value visitStatement(final @NotNull StatementExpression expression) { + switch (expression.op()) { + case BREAK: { + this.flag = StatementExpression.Op.BREAK; + break; + } + case CONTINUE: { + this.flag = StatementExpression.Op.CONTINUE; + break; + } + } + return NumberValue.zero(); + } + + @Override + public @NotNull Value visitString(final @NotNull StringExpression expression) { + return StringValue.of(expression.value()); + } + + @Override + public @NotNull Value visitTernaryConditional(@NotNull TernaryConditionalExpression expression) { + final Value conditionResult = expression.condition().visit(this); + return conditionResult.getAsBoolean() + ? expression.trueExpression().visit(this) + : expression.falseExpression().visit(this); + } + + @Override + public Value visit(final @NotNull Expression expression) { + throw new UnsupportedOperationException("Unsupported expression type: " + expression); + } + + private interface Evaluator { + @NotNull Value eval(ExpressionInterpreter evaluator, Expression a, Expression b); + } + + private interface BooleanOperator { + boolean operate(LazyEvaluableBoolean a, LazyEvaluableBoolean b); + } + + interface LazyEvaluableBoolean { + boolean eval(); + } + + interface LazyEvaluableFloat { + float eval(); + } + + private interface Comparator { + boolean compare(LazyEvaluableFloat a, LazyEvaluableFloat b); + + } + + private interface ArithmeticOperator { + float operate(LazyEvaluableFloat a, LazyEvaluableFloat b); + } + + public static class FunctionArguments implements Function.Arguments { + public static final Function.Arguments EMPTY = new FunctionArguments(new Function.Argument[0]); + + private final Function.Argument[] arguments; + private int next; + + FunctionArguments(final @NotNull Function.Argument @NotNull [] arguments) { + this.arguments = requireNonNull(arguments, "arguments"); + } + + @Override + public Function.@NotNull Argument next() { + if (next < arguments.length) { + return arguments[next++]; + } else { + return EmptyFunctionArgument.EMPTY; + } + } + + @Override + public int length() { + return arguments.length; + } + } + + private static class EmptyFunctionArgument implements Function.Argument { + static final Function.Argument EMPTY = new EmptyFunctionArgument(); + + @Override + public @Nullable Expression expression() { + return null; + } + + @Override + public @Nullable Value eval() { + return NumberValue.zero(); + } + } + + private class FunctionArgumentImpl implements Function.Argument { + private final Expression expression; + + FunctionArgumentImpl(final @NotNull Expression expression) { + this.expression = expression; + } + + @Override + public @NotNull Expression expression() { + return expression; + } + + @Override + public @Nullable Value eval() { + return expression.visit(ExpressionInterpreter.this); + } + } +} diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java b/runtime/src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java index e3af7cd..6efa47e 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/JavaTypes.java b/runtime/src/main/java/team/unnamed/mocha/runtime/JavaTypes.java index a161da7..92b2fb5 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/JavaTypes.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/JavaTypes.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java b/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java index 16b1354..5eb6061 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java @@ -1,394 +1,394 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.MolangParser; -import team.unnamed.mocha.parser.ParseException; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.parser.ast.FloatExpression; -import team.unnamed.mocha.runtime.binding.Binding; -import team.unnamed.mocha.runtime.binding.JavaObjectBinding; -import team.unnamed.mocha.runtime.standard.MochaMath; -import team.unnamed.mocha.runtime.value.MutableObjectBinding; -import team.unnamed.mocha.runtime.value.NumberValue; -import team.unnamed.mocha.runtime.value.ObjectValue; -import team.unnamed.mocha.runtime.value.Value; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.UncheckedIOException; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Supplier; - -import static java.util.Objects.requireNonNull; - -/** - * Stateful entry point for interpretation. Holds the entity, the global - * {@link Scope} and the runtime-side configuration (parse exception handler, - * "warn on reflective function usage" flag), and exposes {@code eval(...)} / - * {@code prepareEval(...)} variants plus binding helpers. - * - *

Each {@code eval} call gets its own copy of the scope with a fresh - * {@code temp} / {@code t} binding so concurrent or nested evaluations do - * not see each other's local state.

- * - * @since 5.0.0 - */ -public final class MolangInterpreter { - private final T entity; - private final Scope scope; - private Consumer<@NotNull ParseException> parseExceptionHandler; - private boolean warnOnReflectiveFunctionUsage; - - public MolangInterpreter(final @Nullable T entity, final @NotNull Scope scope) { - this.entity = entity; - this.scope = requireNonNull(scope, "scope"); - } - - /** - * Creates an interpreter with the given {@code entity} and an empty, - * user-built {@link Scope}. - * - * @since 5.0.0 - */ - @Contract("_, _ -> new") - public static @NotNull MolangInterpreter create(final @Nullable T entity, final @NotNull Consumer scopeBuilder) { - final Scope.Builder builder = Scope.builder(); - scopeBuilder.accept(builder); - return new MolangInterpreter<>(entity, builder.build()); - } - - @Contract("_ -> new") - public static @NotNull MolangInterpreter create(final @Nullable T entity) { - return create(entity, b -> { - }); - } - - @Contract("-> new") - public static @NotNull MolangInterpreter create() { - return create(null); - } - - /** - * Creates an interpreter pre-populated with the standard - * {@code math} / {@code variable} / {@code v} bindings. Lives in the - * runtime module so a caller that only needs interpretation does not have - * to depend on the compiler module. - * - * @since 5.0.0 - */ - @Contract("_ -> new") - public static @NotNull MolangInterpreter standard(final @Nullable T entity) { - return create(entity, builder -> { - builder.set("math", JavaObjectBinding.of(MochaMath.class, null, new MochaMath())); - final MutableObjectBinding variableBinding = new MutableObjectBinding(); - builder.set("variable", variableBinding); - builder.set("v", variableBinding); - }); - } - - @Contract("-> new") - public static @NotNull MolangInterpreter standard() { - return standard(null); - } - - public @Nullable T entity() { - return entity; - } - - /** - * Returns the bindings for this interpreter instance. - * - * @since 3.0.0 - */ - public @NotNull Scope scope() { - return scope; - } - - //#region INTERPRETER API - - /** - * Evaluates the given {@code expressions}, these expressions are already - * parsed and are interpreted as fast as possible. - * - * @param expressions The expressions to evaluate. - * @param scopeConsumer Optional callback to populate per-call bindings on - * the local scope copy before evaluation. - * @return The result of the evaluation. - * @since 4.1.0 - */ - public float eval(final @NotNull List expressions, final @Nullable Consumer scopeConsumer) { - if (expressions.size() == 1 && expressions.get(0) instanceof FloatExpression expression) { - return expression.value(); - } - - final Scope local = scope.copy(); - { - final MutableObjectBinding temp = new MutableObjectBinding(); - local.set("temp", temp); - local.set("t", temp); - } - if (scopeConsumer != null && !local.readOnly()) scopeConsumer.accept(local); - local.readOnly(true); - - final ExpressionInterpreter evaluator = new ExpressionInterpreter<>(entity, local); - evaluator.warnOnReflectiveFunctionUsage(warnOnReflectiveFunctionUsage); - Value lastResult = NumberValue.zero(); - - for (final Expression expression : expressions) { - lastResult = expression.visit(evaluator); - final Value returnValue = evaluator.popReturnValue(); - if (returnValue != null) { - lastResult = returnValue; - break; - } - } - - return lastResult == null ? 0F : lastResult.getAsNumber(); - } - - /** - * @see #eval(List, Consumer) - * @since 3.0.0 - */ - public float eval(final @NotNull List expressions) { - return eval(expressions, null); - } - - /** - * Parses and evaluates the given Molang source. - * - *

Note that this method does not cache parsed expressions. If you want - * to re-use parsed expressions, parse them yourself with - * {@link MolangParser} and use {@link #eval(List, Consumer)}.

- * - *

Parse errors are routed through the handler set by - * {@link #handleParseExceptions(Consumer)} and the call returns {@code 0}.

- * - * @since 4.1.0 - */ - public float eval(final @NotNull Reader source, final @Nullable Consumer scopeConsumer) { - final List parsed; - try { - parsed = MolangParser.parseAll(source); - } catch (final ParseException e) { - if (parseExceptionHandler != null) parseExceptionHandler.accept(e); - return 0F; - } catch (final IOException e) { - throw new UncheckedIOException("Failed to read from given reader", e); - } - return eval(parsed, scopeConsumer); - } - - /** - * @see #eval(Reader, Consumer) - * @since 3.0.0 - */ - public float eval(final @NotNull Reader source) { - return eval(source, null); - } - - /** - * Parses and evaluates the given Molang source string. - * - * @see #eval(Reader, Consumer) - * @since 4.1.0 - */ - public float eval(final @NotNull String source, final @Nullable Consumer scopeConsumer) { - requireNonNull(source, "source"); - try (final StringReader reader = new StringReader(source)) { - return eval(reader, scopeConsumer); - } - } - - /** - * @see #eval(String, Consumer) - * @since 3.0.0 - */ - public float eval(final @NotNull String source) { - return eval(source, null); - } - - /** - * Parses {@code reader} once and returns a {@link Supplier} that runs the - * cached AST through the interpreter on each call. Parse errors go through - * {@link #handleParseExceptions(Consumer)}; a failed parse yields a - * supplier that always produces {@code 0}. - * - * @since 4.1.0 - */ - public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull Reader reader, final @Nullable Consumer scopeConsumer) { - final List parsed; - try { - parsed = MolangParser.parseAll(reader); - } catch (final ParseException e) { - if (parseExceptionHandler != null) parseExceptionHandler.accept(e); - return () -> 0F; - } catch (final IOException e) { - throw new UncheckedIOException("Failed to read from given reader", e); - } - return () -> eval(parsed, scopeConsumer); - } - - /** - * @see #prepareEval(Reader, Consumer) - * @since 3.0.0 - */ - public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull Reader reader) { - return prepareEval(reader, null); - } - - /** - * @see #prepareEval(Reader, Consumer) - * @since 4.1.0 - */ - public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull String code, final @Nullable Consumer scopeConsumer) { - requireNonNull(code, "code"); - try (final StringReader reader = new StringReader(code)) { - return prepareEval(reader, scopeConsumer); - } - } - - /** - * @see #prepareEval(String, Consumer) - * @since 3.0.0 - */ - public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull String code) { - return prepareEval(code, null); - } - - //#endregion - - //#region BINDING API - - /** - * Binds the given {@code clazz}'s static fields and methods into this - * interpreter's {@link Scope}. - * - *

Fields and methods are bound in the following format:

- *
-     *     namespace.field
-     *     namespace.method()
-     *     namespace.method(arg1, arg2)
-     * 
- * - *

Where {@code namespace} comes from the class' {@link Binding} - * annotation, and field/method names from {@link Binding} annotations on - * the members.

- * - * @see Binding - * @since 3.0.0 - */ - public void bind(final @NotNull Class clazz) { - final JavaObjectBinding javaObjectBinding = JavaObjectBinding.of(clazz, null, null); - for (final String name : javaObjectBinding.names()) { - scope.set(name, javaObjectBinding); - } - } - - /** - * Binds the given {@code instance}'s non-static fields and methods. - * - *

Fields and methods are bound in the format:

- *
-     *     name.field
-     *     name.method()
-     *     name.method(arg1, arg2)
-     * 
- * - *

Where {@code name} comes from the {@code name} parameter, and field - * /method names from {@link Binding} annotations.

- * - * @param clazz The instance's class (or interface) to use. - * @param instance The instance to bind. - * @param name The name to bind the instance to. - * @param aliases Additional names to bind the instance to. - * @param The instance's type. - * @since 3.0.0 - */ - public void bindInstance(final @NotNull Class clazz, final @NotNull B instance, final @NotNull String name, final @NotNull String @NotNull ... aliases) { - final JavaObjectBinding javaObjectBinding = JavaObjectBinding.of(clazz, instance, null); - scope.set(name, javaObjectBinding); - for (final String alias : aliases) { - scope.set(alias, javaObjectBinding); - } - } - - //#endregion - - //#region CONFIGURATION API - - public boolean warnOnReflectiveFunctionUsage() { - return warnOnReflectiveFunctionUsage; - } - - /** - * Sets the boolean value for the "warn on reflective function usage" - * option. - * - *

When set to true, {@link #eval} may log a warning when evaluating - * code that includes a call to a function that was registered using only - * annotations and therefore has to be invoked via Reflection, taking some - * extra time.

- * - *

Note that this behavior can be avoided by setting an - * {@link ObjectValue} when binding static or non-static methods and fields.

- * - *

By default this is false.

- * - * @return This interpreter instance. - * @since 3.0.0 - */ - @Contract("_ -> this") - public @NotNull MolangInterpreter warnOnReflectiveFunctionUsage(final boolean warnOnReflectiveFunctionUsage) { - this.warnOnReflectiveFunctionUsage = warnOnReflectiveFunctionUsage; - return this; - } - - /** - * Sets the {@link ParseException} handler. This handler will be called - * whenever an internal call to {@link MolangParser} from - * {@link #eval(Reader, Consumer)} or {@link #prepareEval(Reader, Consumer)} - * fails. - * - *

Usually useful for logging/debugging purposes.

- * - *

By default this is null.

- * - * @return This interpreter instance. - * @since 3.0.0 - */ - @Contract("_ -> this") - public @NotNull MolangInterpreter handleParseExceptions(final @Nullable Consumer<@NotNull ParseException> exceptionHandler) { - this.parseExceptionHandler = exceptionHandler; - return this; - } - - //#endregion -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import team.unnamed.mocha.parser.MolangParser; +import team.unnamed.mocha.parser.ParseException; +import team.unnamed.mocha.parser.ast.Expression; +import team.unnamed.mocha.parser.ast.FloatExpression; +import team.unnamed.mocha.runtime.binding.Binding; +import team.unnamed.mocha.runtime.binding.JavaObjectBinding; +import team.unnamed.mocha.runtime.standard.MochaMath; +import team.unnamed.mocha.runtime.value.MutableObjectBinding; +import team.unnamed.mocha.runtime.value.NumberValue; +import team.unnamed.mocha.runtime.value.ObjectValue; +import team.unnamed.mocha.runtime.value.Value; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.UncheckedIOException; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import static java.util.Objects.requireNonNull; + +/** + * Stateful entry point for interpretation. Holds the entity, the global + * {@link Scope} and the runtime-side configuration (parse exception handler, + * "warn on reflective function usage" flag), and exposes {@code eval(...)} / + * {@code prepareEval(...)} variants plus binding helpers. + * + *

Each {@code eval} call gets its own copy of the scope with a fresh + * {@code temp} / {@code t} binding so concurrent or nested evaluations do + * not see each other's local state.

+ * + * @since 5.0.0 + */ +public final class MolangInterpreter { + private final T entity; + private final Scope scope; + private Consumer<@NotNull ParseException> parseExceptionHandler; + private boolean warnOnReflectiveFunctionUsage; + + public MolangInterpreter(final @Nullable T entity, final @NotNull Scope scope) { + this.entity = entity; + this.scope = requireNonNull(scope, "scope"); + } + + /** + * Creates an interpreter with the given {@code entity} and an empty, + * user-built {@link Scope}. + * + * @since 5.0.0 + */ + @Contract("_, _ -> new") + public static @NotNull MolangInterpreter create(final @Nullable T entity, final @NotNull Consumer scopeBuilder) { + final Scope.Builder builder = Scope.builder(); + scopeBuilder.accept(builder); + return new MolangInterpreter<>(entity, builder.build()); + } + + @Contract("_ -> new") + public static @NotNull MolangInterpreter create(final @Nullable T entity) { + return create(entity, b -> { + }); + } + + @Contract("-> new") + public static @NotNull MolangInterpreter create() { + return create(null); + } + + /** + * Creates an interpreter pre-populated with the standard + * {@code math} / {@code variable} / {@code v} bindings. Lives in the + * runtime module so a caller that only needs interpretation does not have + * to depend on the compiler module. + * + * @since 5.0.0 + */ + @Contract("_ -> new") + public static @NotNull MolangInterpreter standard(final @Nullable T entity) { + return create(entity, builder -> { + builder.set("math", JavaObjectBinding.of(MochaMath.class, null, new MochaMath())); + final MutableObjectBinding variableBinding = new MutableObjectBinding(); + builder.set("variable", variableBinding); + builder.set("v", variableBinding); + }); + } + + @Contract("-> new") + public static @NotNull MolangInterpreter standard() { + return standard(null); + } + + public @Nullable T entity() { + return entity; + } + + /** + * Returns the bindings for this interpreter instance. + * + * @since 3.0.0 + */ + public @NotNull Scope scope() { + return scope; + } + + //#region INTERPRETER API + + /** + * Evaluates the given {@code expressions}, these expressions are already + * parsed and are interpreted as fast as possible. + * + * @param expressions The expressions to evaluate. + * @param scopeConsumer Optional callback to populate per-call bindings on + * the local scope copy before evaluation. + * @return The result of the evaluation. + * @since 4.1.0 + */ + public float eval(final @NotNull List expressions, final @Nullable Consumer scopeConsumer) { + if (expressions.size() == 1 && expressions.get(0) instanceof FloatExpression expression) { + return expression.value(); + } + + final Scope local = scope.copy(); + { + final MutableObjectBinding temp = new MutableObjectBinding(); + local.set("temp", temp); + local.set("t", temp); + } + if (scopeConsumer != null && !local.readOnly()) scopeConsumer.accept(local); + local.readOnly(true); + + final ExpressionInterpreter evaluator = new ExpressionInterpreter<>(entity, local); + evaluator.warnOnReflectiveFunctionUsage(warnOnReflectiveFunctionUsage); + Value lastResult = NumberValue.zero(); + + for (final Expression expression : expressions) { + lastResult = expression.visit(evaluator); + final Value returnValue = evaluator.popReturnValue(); + if (returnValue != null) { + lastResult = returnValue; + break; + } + } + + return lastResult == null ? 0F : lastResult.getAsNumber(); + } + + /** + * @see #eval(List, Consumer) + * @since 3.0.0 + */ + public float eval(final @NotNull List expressions) { + return eval(expressions, null); + } + + /** + * Parses and evaluates the given Molang source. + * + *

Note that this method does not cache parsed expressions. If you want + * to re-use parsed expressions, parse them yourself with + * {@link MolangParser} and use {@link #eval(List, Consumer)}.

+ * + *

Parse errors are routed through the handler set by + * {@link #handleParseExceptions(Consumer)} and the call returns {@code 0}.

+ * + * @since 4.1.0 + */ + public float eval(final @NotNull Reader source, final @Nullable Consumer scopeConsumer) { + final List parsed; + try { + parsed = MolangParser.parseAll(source); + } catch (final ParseException e) { + if (parseExceptionHandler != null) parseExceptionHandler.accept(e); + return 0F; + } catch (final IOException e) { + throw new UncheckedIOException("Failed to read from given reader", e); + } + return eval(parsed, scopeConsumer); + } + + /** + * @see #eval(Reader, Consumer) + * @since 3.0.0 + */ + public float eval(final @NotNull Reader source) { + return eval(source, null); + } + + /** + * Parses and evaluates the given Molang source string. + * + * @see #eval(Reader, Consumer) + * @since 4.1.0 + */ + public float eval(final @NotNull String source, final @Nullable Consumer scopeConsumer) { + requireNonNull(source, "source"); + try (final StringReader reader = new StringReader(source)) { + return eval(reader, scopeConsumer); + } + } + + /** + * @see #eval(String, Consumer) + * @since 3.0.0 + */ + public float eval(final @NotNull String source) { + return eval(source, null); + } + + /** + * Parses {@code reader} once and returns a {@link Supplier} that runs the + * cached AST through the interpreter on each call. Parse errors go through + * {@link #handleParseExceptions(Consumer)}; a failed parse yields a + * supplier that always produces {@code 0}. + * + * @since 4.1.0 + */ + public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull Reader reader, final @Nullable Consumer scopeConsumer) { + final List parsed; + try { + parsed = MolangParser.parseAll(reader); + } catch (final ParseException e) { + if (parseExceptionHandler != null) parseExceptionHandler.accept(e); + return () -> 0F; + } catch (final IOException e) { + throw new UncheckedIOException("Failed to read from given reader", e); + } + return () -> eval(parsed, scopeConsumer); + } + + /** + * @see #prepareEval(Reader, Consumer) + * @since 3.0.0 + */ + public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull Reader reader) { + return prepareEval(reader, null); + } + + /** + * @see #prepareEval(Reader, Consumer) + * @since 4.1.0 + */ + public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull String code, final @Nullable Consumer scopeConsumer) { + requireNonNull(code, "code"); + try (final StringReader reader = new StringReader(code)) { + return prepareEval(reader, scopeConsumer); + } + } + + /** + * @see #prepareEval(String, Consumer) + * @since 3.0.0 + */ + public @NotNull Supplier<@NotNull Float> prepareEval(final @NotNull String code) { + return prepareEval(code, null); + } + + //#endregion + + //#region BINDING API + + /** + * Binds the given {@code clazz}'s static fields and methods into this + * interpreter's {@link Scope}. + * + *

Fields and methods are bound in the following format:

+ *
+     *     namespace.field
+     *     namespace.method()
+     *     namespace.method(arg1, arg2)
+     * 
+ * + *

Where {@code namespace} comes from the class' {@link Binding} + * annotation, and field/method names from {@link Binding} annotations on + * the members.

+ * + * @see Binding + * @since 3.0.0 + */ + public void bind(final @NotNull Class clazz) { + final JavaObjectBinding javaObjectBinding = JavaObjectBinding.of(clazz, null, null); + for (final String name : javaObjectBinding.names()) { + scope.set(name, javaObjectBinding); + } + } + + /** + * Binds the given {@code instance}'s non-static fields and methods. + * + *

Fields and methods are bound in the format:

+ *
+     *     name.field
+     *     name.method()
+     *     name.method(arg1, arg2)
+     * 
+ * + *

Where {@code name} comes from the {@code name} parameter, and field + * /method names from {@link Binding} annotations.

+ * + * @param clazz The instance's class (or interface) to use. + * @param instance The instance to bind. + * @param name The name to bind the instance to. + * @param aliases Additional names to bind the instance to. + * @param The instance's type. + * @since 3.0.0 + */ + public void bindInstance(final @NotNull Class clazz, final @NotNull B instance, final @NotNull String name, final @NotNull String @NotNull ... aliases) { + final JavaObjectBinding javaObjectBinding = JavaObjectBinding.of(clazz, instance, null); + scope.set(name, javaObjectBinding); + for (final String alias : aliases) { + scope.set(alias, javaObjectBinding); + } + } + + //#endregion + + //#region CONFIGURATION API + + public boolean warnOnReflectiveFunctionUsage() { + return warnOnReflectiveFunctionUsage; + } + + /** + * Sets the boolean value for the "warn on reflective function usage" + * option. + * + *

When set to true, {@link #eval} may log a warning when evaluating + * code that includes a call to a function that was registered using only + * annotations and therefore has to be invoked via Reflection, taking some + * extra time.

+ * + *

Note that this behavior can be avoided by setting an + * {@link ObjectValue} when binding static or non-static methods and fields.

+ * + *

By default this is false.

+ * + * @return This interpreter instance. + * @since 3.0.0 + */ + @Contract("_ -> this") + public @NotNull MolangInterpreter warnOnReflectiveFunctionUsage(final boolean warnOnReflectiveFunctionUsage) { + this.warnOnReflectiveFunctionUsage = warnOnReflectiveFunctionUsage; + return this; + } + + /** + * Sets the {@link ParseException} handler. This handler will be called + * whenever an internal call to {@link MolangParser} from + * {@link #eval(Reader, Consumer)} or {@link #prepareEval(Reader, Consumer)} + * fails. + * + *

Usually useful for logging/debugging purposes.

+ * + *

By default this is null.

+ * + * @return This interpreter instance. + * @since 3.0.0 + */ + @Contract("_ -> this") + public @NotNull MolangInterpreter handleParseExceptions(final @Nullable Consumer<@NotNull ParseException> exceptionHandler) { + this.parseExceptionHandler = exceptionHandler; + return this; + } + + //#endregion +} diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/Scope.java b/runtime/src/main/java/team/unnamed/mocha/runtime/Scope.java index 2b7688c..8fd7575 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/Scope.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/Scope.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.jetbrains.annotations.NotNull; import team.unnamed.mocha.runtime.value.ObjectValue; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java b/runtime/src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java index ae8ab8e..a528454 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/TypeCastException.java b/runtime/src/main/java/team/unnamed/mocha/runtime/TypeCastException.java index 1b0815d..7699a0e 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/TypeCastException.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/TypeCastException.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime; import java.io.Serial; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java index 40e5ba8..d36f2e9 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.binding; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.binding; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Binding.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Binding.java index 95e26ed..f2b9c2d 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Binding.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Binding.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.binding; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.binding; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Entity.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Entity.java index 194fb60..56d5759 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Entity.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Entity.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.binding; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.binding; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java index 1b8ee58..21c23b2 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.binding; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.binding; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java index 26297e8..12458f5 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.binding; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.binding; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java index dbacfcb..730cf54 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.binding; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.binding; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java index fa8ec4e..06c83d1 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.binding; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.binding; public interface Lazy { T get(); diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java index 4cc5fba..559ea24 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.binding; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.binding; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java index 0c09615..1127949 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.binding; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.binding; /** * A registered binding. This is either a field or a method. diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java index 409e8c9..5a3e23a 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java @@ -1,4 +1,4 @@ -@ReflectionSupport(ReflectionSupport.Level.FULL) -package team.unnamed.mocha.runtime.binding; - +@ReflectionSupport(ReflectionSupport.Level.FULL) +package team.unnamed.mocha.runtime.binding; + import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java b/runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java index f341450..eaa9cc2 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java @@ -1,4 +1,4 @@ -@ReflectionSupport(ReflectionSupport.Level.FULL) -package team.unnamed.mocha.runtime.standard; - +@ReflectionSupport(ReflectionSupport.Level.FULL) +package team.unnamed.mocha.runtime.standard; + import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java index c850792..becd111 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/Function.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/Function.java index 17fbfd9..8adb65b 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/Function.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/Function.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java index 4d98ac4..d92aa16 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; public final class JavaValue implements Value { private final Object value; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java index a0e1403..8a0802b 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java index 12c96d0..65a80d4 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java @@ -1,86 +1,86 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public final class NumberValue implements Value { - private static final NumberValue ONE = new NumberValue(1F); - private static final NumberValue ZERO = new NumberValue(0F); - - private final float value; - - private NumberValue(final float value) { - this.value = normalize(value); - } - - public static @NotNull NumberValue of(final double value) { - return NumberValue.of((float) value); - } - - public static @NotNull NumberValue of(final float value) { - if (value == ONE.value()) return ONE; - if (value == ZERO.value()) return ZERO; - return new NumberValue(value); - } - - public static @NotNull NumberValue one() { - return ONE; - } - - public static @NotNull NumberValue zero() { - return ZERO; - } - - public static double normalize(final double value) { - return Double.isNaN(value) || Double.isInfinite(value) ? 0D : value; - } - - public static float normalize(final float value) { - return Float.isNaN(value) || Float.isInfinite(value) ? 0F : value; - } - - public float value() { - return value; - } - - @Override - public @NotNull String toString() { - return "NumberValue(" + value + ')'; - } - - @Override - public boolean equals(final @Nullable Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final NumberValue that = (NumberValue) o; - return Float.compare(that.value, value) == 0; - } - - @Override - public int hashCode() { - return Float.hashCode(value); - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class NumberValue implements Value { + private static final NumberValue ONE = new NumberValue(1F); + private static final NumberValue ZERO = new NumberValue(0F); + + private final float value; + + private NumberValue(final float value) { + this.value = normalize(value); + } + + public static @NotNull NumberValue of(final double value) { + return NumberValue.of((float) value); + } + + public static @NotNull NumberValue of(final float value) { + if (value == ONE.value()) return ONE; + if (value == ZERO.value()) return ZERO; + return new NumberValue(value); + } + + public static @NotNull NumberValue one() { + return ONE; + } + + public static @NotNull NumberValue zero() { + return ZERO; + } + + public static double normalize(final double value) { + return Double.isNaN(value) || Double.isInfinite(value) ? 0D : value; + } + + public static float normalize(final float value) { + return Float.isNaN(value) || Float.isInfinite(value) ? 0F : value; + } + + public float value() { + return value; + } + + @Override + public @NotNull String toString() { + return "NumberValue(" + value + ')'; + } + + @Override + public boolean equals(final @Nullable Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final NumberValue that = (NumberValue) o; + return Float.compare(that.value, value) == 0; + } + + @Override + public int hashCode() { + return Float.hashCode(value); + } +} diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java index e9b8ba9..77e0d1b 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java index fad0ecd..a189ff3 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java index 538697e..2f787b3 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java @@ -1,101 +1,101 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Collections; -import java.util.Map; - -public non-sealed interface ObjectValue extends Value { - /** - * Returns the property for the given name ignoring - * its case. This method is CASE-INSENSITIVE. - * - * @param name The name of the property - * @return The property for the given name - * @since 3.0.0 - */ - @Nullable ObjectProperty getProperty(final @NotNull String name); - - /** - * Gets the value of the specified property, - * ignoring its casing. This method is - * CASE-INSENSITIVE. - * - * @param name The name of the property - * @return The value of the property - * @since 3.0.0 - */ - default @NotNull Value get(final @NotNull String name) { - final ObjectProperty property = getProperty(name); - if (property == null) { - return Value.nil(); - } else { - return property.value(); - } - } - - default boolean set(final @NotNull String name, final @Nullable Value value) { - return false; - } - - default @NotNull Map entries() { - return Collections.emptyMap(); - } - - // :) overloads - default void setFunction(final @NotNull String name, final @NotNull ObjectValue.FloatFunction function) { - set(name, (Function) (ctx, args) -> NumberValue.of(function.apply())); - } - - default void setFunction(final @NotNull String name, final @NotNull ObjectValue.FloatFunction1 function) { - set(name, (Function) (ctx, args) -> NumberValue.of(function.apply(args.next().eval().getAsNumber()))); - } - - default void setFunction(final @NotNull String name, final @NotNull ObjectValue.FloatFunction2 function) { - set(name, (Function) (ctx, args) -> NumberValue.of(function.apply(args.next().eval().getAsNumber(), args.next().eval().getAsNumber()))); - } - - default void setFunction(final @NotNull String name, final @NotNull ObjectValue.FloatFunction3 function) { - set(name, (Function) (ctx, args) -> NumberValue.of(function.apply(args.next().eval().getAsNumber(), args.next().eval().getAsNumber(), args.next().eval().getAsNumber()))); - } - - interface FloatFunction { - float apply(); - } - - interface FloatFunction1 { - float apply(float n); - } - - interface FloatFunction2 { - float apply(float n1, float n2); - } - - interface FloatFunction3 { - float apply(float n1, float n2, float n3); - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.Map; + +public non-sealed interface ObjectValue extends Value { + /** + * Returns the property for the given name ignoring + * its case. This method is CASE-INSENSITIVE. + * + * @param name The name of the property + * @return The property for the given name + * @since 3.0.0 + */ + @Nullable ObjectProperty getProperty(final @NotNull String name); + + /** + * Gets the value of the specified property, + * ignoring its casing. This method is + * CASE-INSENSITIVE. + * + * @param name The name of the property + * @return The value of the property + * @since 3.0.0 + */ + default @NotNull Value get(final @NotNull String name) { + final ObjectProperty property = getProperty(name); + if (property == null) { + return Value.nil(); + } else { + return property.value(); + } + } + + default boolean set(final @NotNull String name, final @Nullable Value value) { + return false; + } + + default @NotNull Map entries() { + return Collections.emptyMap(); + } + + // :) overloads + default void setFunction(final @NotNull String name, final @NotNull ObjectValue.FloatFunction function) { + set(name, (Function) (ctx, args) -> NumberValue.of(function.apply())); + } + + default void setFunction(final @NotNull String name, final @NotNull ObjectValue.FloatFunction1 function) { + set(name, (Function) (ctx, args) -> NumberValue.of(function.apply(args.next().eval().getAsNumber()))); + } + + default void setFunction(final @NotNull String name, final @NotNull ObjectValue.FloatFunction2 function) { + set(name, (Function) (ctx, args) -> NumberValue.of(function.apply(args.next().eval().getAsNumber(), args.next().eval().getAsNumber()))); + } + + default void setFunction(final @NotNull String name, final @NotNull ObjectValue.FloatFunction3 function) { + set(name, (Function) (ctx, args) -> NumberValue.of(function.apply(args.next().eval().getAsNumber(), args.next().eval().getAsNumber(), args.next().eval().getAsNumber()))); + } + + interface FloatFunction { + float apply(); + } + + interface FloatFunction1 { + float apply(float n); + } + + interface FloatFunction2 { + float apply(float n1, float n2); + } + + interface FloatFunction3 { + float apply(float n1, float n2, float n3); + } +} diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/StringValue.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/StringValue.java index 33c5163..e6ae66b 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/StringValue.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/StringValue.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/Value.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/Value.java index 29ea9f5..a6f3488 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/Value.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/Value.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java index 666814c..7700369 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java @@ -1,4 +1,4 @@ -@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.runtime.value; - +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package team.unnamed.mocha.runtime.value; + import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java b/runtime/src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java index b85f7a4..f889299 100644 --- a/runtime/src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java +++ b/runtime/src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.util; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.util; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java b/runtime/src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java index 40f6128..5f39f84 100644 --- a/runtime/src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java +++ b/runtime/src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java @@ -1,49 +1,49 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.runtime.value; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class ValueOfTest { - @Test - void test() { - assertEquals(NumberValue.of(5), Value.of(5)); - assertEquals(StringValue.of("hello"), Value.of("hello")); - assertEquals(NumberValue.of(1), Value.of(true)); - assertEquals(NumberValue.zero(), Value.of(false)); - assertEquals(NumberValue.zero(), Value.of(null)); - assertEquals(NumberValue.zero(), Value.of(new Object())); - assertEquals(ArrayValue.of(), Value.of(new Object[0])); - assertEquals(ArrayValue.of(), Value.of(new int[0])); - assertEquals(ArrayValue.of(), Value.of(new float[0])); - assertEquals(ArrayValue.of(NumberValue.of(1)), Value.of(new int[]{1})); - assertEquals(ArrayValue.of(NumberValue.of(1)), Value.of(new float[]{1})); - assertEquals(ArrayValue.of(NumberValue.of(1)), Value.of(new Object[]{1})); - assertEquals(ArrayValue.of(NumberValue.of(1), NumberValue.of(2)), Value.of(new int[]{1, 2})); - assertEquals(ArrayValue.of(NumberValue.of(1), NumberValue.of(2)), Value.of(new float[]{1, 2})); - assertEquals(ArrayValue.of(NumberValue.of(1), StringValue.of("hello"), NumberValue.zero()), Value.of(new Object[]{1, "hello", false})); - } -} +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.runtime.value; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ValueOfTest { + @Test + void test() { + assertEquals(NumberValue.of(5), Value.of(5)); + assertEquals(StringValue.of("hello"), Value.of("hello")); + assertEquals(NumberValue.of(1), Value.of(true)); + assertEquals(NumberValue.zero(), Value.of(false)); + assertEquals(NumberValue.zero(), Value.of(null)); + assertEquals(NumberValue.zero(), Value.of(new Object())); + assertEquals(ArrayValue.of(), Value.of(new Object[0])); + assertEquals(ArrayValue.of(), Value.of(new int[0])); + assertEquals(ArrayValue.of(), Value.of(new float[0])); + assertEquals(ArrayValue.of(NumberValue.of(1)), Value.of(new int[]{1})); + assertEquals(ArrayValue.of(NumberValue.of(1)), Value.of(new float[]{1})); + assertEquals(ArrayValue.of(NumberValue.of(1)), Value.of(new Object[]{1})); + assertEquals(ArrayValue.of(NumberValue.of(1), NumberValue.of(2)), Value.of(new int[]{1, 2})); + assertEquals(ArrayValue.of(NumberValue.of(1), NumberValue.of(2)), Value.of(new float[]{1, 2})); + assertEquals(ArrayValue.of(NumberValue.of(1), StringValue.of("hello"), NumberValue.zero()), Value.of(new Object[]{1, "hello", false})); + } +} diff --git a/runtime/src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java b/runtime/src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java index 7f3e49e..8328853 100644 --- a/runtime/src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java +++ b/runtime/src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha.util; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha.util; import org.junit.jupiter.api.Test; diff --git a/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java b/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java index 5a7918e..0bc72c4 100644 --- a/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java +++ b/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java @@ -1,27 +1,27 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha; +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package team.unnamed.mocha; import com.bedrockk.molang.MoLang; import com.bedrockk.molang.parser.Expression; From 68be2f82730745d6707c5e43e8f1791953d2ce40 Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sun, 10 May 2026 17:25:11 +0700 Subject: [PATCH 07/15] j2objc --- .../java/team/unnamed/mocha/runtime/CompileVisitResult.java | 2 ++ .../team/unnamed/mocha/runtime/FunctionCompileState.java | 2 ++ .../main/java/team/unnamed/mocha/runtime/MolangCompiler.java | 2 ++ .../team/unnamed/mocha/runtime/MolangCompilingVisitor.java | 2 ++ .../src/main/java/team/unnamed/mocha/util/ClassFileUtil.java | 2 ++ .../team/unnamed/mocha/runtime/ExpressionInterpreter.java | 5 +++-- .../java/team/unnamed/mocha/runtime/MolangInterpreter.java | 5 ++++- 7 files changed, 17 insertions(+), 3 deletions(-) diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java index b7889a9..6aa41b2 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java @@ -23,11 +23,13 @@ */ package team.unnamed.mocha.runtime; +import com.google.j2objc.annotations.J2ObjCIncompatible; import org.jetbrains.annotations.Nullable; import java.lang.constant.ClassDesc; import java.lang.constant.ConstantDescs; +@J2ObjCIncompatible final class CompileVisitResult { static final CompileVisitResult FLOAT = new CompileVisitResult(ConstantDescs.CD_float); static final CompileVisitResult DOUBLE = new CompileVisitResult(ConstantDescs.CD_double); diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java index 2e6423b..6e4cf59 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java @@ -23,6 +23,7 @@ */ package team.unnamed.mocha.runtime; +import com.google.j2objc.annotations.J2ObjCIncompatible; import org.jetbrains.annotations.NotNull; import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; @@ -33,6 +34,7 @@ import static java.util.Objects.requireNonNull; +@J2ObjCIncompatible final class FunctionCompileState { private final MolangCompiler compiler; diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java index 855bd8a..557724f 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java @@ -23,6 +23,7 @@ */ package team.unnamed.mocha.runtime; +import com.google.j2objc.annotations.J2ObjCIncompatible; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -57,6 +58,7 @@ import static java.util.Objects.requireNonNull; import static team.unnamed.mocha.util.ClassFileUtil.classDescOf; +@J2ObjCIncompatible public final class MolangCompiler { private static final AtomicLong CLASS_NAME_COUNTER = new AtomicLong(); diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java index a2bda2a..970893e 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java @@ -23,6 +23,7 @@ */ package team.unnamed.mocha.runtime; +import com.google.j2objc.annotations.J2ObjCIncompatible; import org.jetbrains.annotations.NotNull; import team.unnamed.mocha.parser.ast.*; import team.unnamed.mocha.runtime.binding.Entity; @@ -52,6 +53,7 @@ import static java.lang.constant.ConstantDescs.*; import static team.unnamed.mocha.util.ClassFileUtil.*; +@J2ObjCIncompatible final class MolangCompilingVisitor implements ExpressionVisitor { private final CodeBuilder codeBuilder; diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/util/ClassFileUtil.java b/runtime-compiler/src/main/java/team/unnamed/mocha/util/ClassFileUtil.java index 197318d..38c0559 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/util/ClassFileUtil.java +++ b/runtime-compiler/src/main/java/team/unnamed/mocha/util/ClassFileUtil.java @@ -23,6 +23,7 @@ */ package team.unnamed.mocha.util; +import com.google.j2objc.annotations.J2ObjCIncompatible; import org.jetbrains.annotations.NotNull; import team.unnamed.mocha.runtime.TypeCastException; @@ -37,6 +38,7 @@ import static java.lang.constant.ConstantDescs.*; import static java.util.Objects.requireNonNull; +@J2ObjCIncompatible public class ClassFileUtil { // Shared wrapper ClassDesc constants to avoid repeated ClassDesc.of() allocations diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java b/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java index 06dfe9d..757b8e8 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java @@ -23,6 +23,7 @@ */ package team.unnamed.mocha.runtime; +import com.google.j2objc.annotations.LoopTranslation; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -277,7 +278,7 @@ public T entity() { if (expr instanceof Function) { final Function callable = (Function) expr; - for (final Value val : arrayIterable) { + for (@LoopTranslation(LoopTranslation.LoopStyle.FAST_ENUMERATION) final Value val : arrayIterable) { // set 'val' as current value // eval (objectExpr.propertyName = val) final Value evaluatedObjectValue = this.eval(objectExpr); @@ -317,7 +318,7 @@ public T entity() { public @NotNull Value visitExecutionScope(final @NotNull ExecutionScopeExpression executionScope) { List expressions = executionScope.expressions(); return (Function) (context, arguments) -> { - for (Expression expression : expressions) { + for (@LoopTranslation(LoopTranslation.LoopStyle.FAST_ENUMERATION) Expression expression : expressions) { // eval expression, ignore result context.eval(expression); diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java b/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java index 5eb6061..5b8ae33 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java +++ b/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java @@ -23,6 +23,8 @@ */ package team.unnamed.mocha.runtime; +import com.google.j2objc.annotations.AutoreleasePool; +import com.google.j2objc.annotations.LoopTranslation; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -143,6 +145,7 @@ public MolangInterpreter(final @Nullable T entity, final @NotNull Scope scope) { * @return The result of the evaluation. * @since 4.1.0 */ + @AutoreleasePool public float eval(final @NotNull List expressions, final @Nullable Consumer scopeConsumer) { if (expressions.size() == 1 && expressions.get(0) instanceof FloatExpression expression) { return expression.value(); @@ -161,7 +164,7 @@ public float eval(final @NotNull List expressions, final @Nullable C evaluator.warnOnReflectiveFunctionUsage(warnOnReflectiveFunctionUsage); Value lastResult = NumberValue.zero(); - for (final Expression expression : expressions) { + for (@LoopTranslation(LoopTranslation.LoopStyle.FAST_ENUMERATION) final Expression expression : expressions) { lastResult = expression.visit(evaluator); final Value returnValue = evaluator.popReturnValue(); if (returnValue != null) { From f16360f7c7588802981212ad3b7e4aa4cd50437e Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Tue, 12 May 2026 00:40:34 +0700 Subject: [PATCH 08/15] java modules! --- .../redlance}/mocha/lexer/Characters.java | 2 +- .../redlance}/mocha/lexer/Cursor.java | 2 +- .../redlance}/mocha/lexer/MolangLexer.java | 2 +- .../mocha/lexer/MolangLexerImpl.java | 2 +- .../redlance}/mocha/lexer/Token.java | 2 +- .../redlance}/mocha/lexer/TokenKind.java | 2 +- .../redlance}/mocha/lexer/package-info.java | 2 +- .../redlance}/mocha/lexer/LexerTest.java | 4 +- .../redlance}/mocha/parser/MolangParser.java | 10 +- .../mocha/parser/MolangParserImpl.java | 9 +- .../mocha/parser/ParseException.java | 4 +- .../mocha/parser/ast/AccessExpression.java | 6 +- .../parser/ast/ArrayAccessExpression.java | 4 +- .../mocha/parser/ast/BinaryExpression.java | 6 +- .../mocha/parser/ast/CallExpression.java | 6 +- .../parser/ast/ExecutionScopeExpression.java | 6 +- .../mocha/parser/ast/Expression.java | 2 +- .../mocha/parser/ast/ExpressionVisitor.java | 2 +- .../mocha/parser/ast/FloatExpression.java | 2 +- .../parser/ast/IdentifierExpression.java | 5 +- .../mocha/parser/ast/StatementExpression.java | 4 +- .../mocha/parser/ast/StringExpression.java | 4 +- .../ast/TernaryConditionalExpression.java | 4 +- .../mocha/parser/ast/UnaryExpression.java | 6 +- .../mocha/parser/ast/package-info.java | 2 +- .../redlance}/mocha/parser/package-info.java | 2 +- .../mocha/parser}/util/ExprBytesUtils.java | 5 +- .../parser}/util/ExpressionListUtils.java | 4 +- .../parser}/util/network/ProtocolUtils.java | 2 +- .../parser}/util/network/VarIntUtils.java | 2 +- .../parser/util/network/package-info.java | 4 + .../mocha/parser/util}/package-info.java | 2 +- .../mocha/parser/ArrayAccessParseTest.java | 7 +- .../redlance}/mocha/parser/CallParseTest.java | 7 +- .../mocha/parser/DoubleParseTest.java | 10 +- .../redlance}/mocha/parser/HierarchyTest.java | 10 +- .../mocha/parser/ParserAssertions.java | 6 +- .../redlance}/mocha/parser/StringTest.java | 4 +- .../mocha/parser/TernaryParseTest.java | 5 +- .../mocha/runtime/CompileVisitResult.java | 2 +- .../mocha/runtime/FunctionCompileState.java | 4 +- .../redlance/mocha/runtime}/MochaEngine.java | 203 +++++++++--------- .../mocha/runtime/MochaFunction.java | 4 +- .../mocha/runtime/MolangCompiler.java | 18 +- .../mocha/runtime/MolangCompilingVisitor.java | 26 +-- .../compiled/MochaCompiledFunction.java | 4 +- .../mocha/runtime/compiled/Named.java | 2 +- .../mocha/runtime/compiled}/package-info.java | 2 +- .../redlance/mocha/runtime}/package-info.java | 2 +- .../mocha/runtime}/util/ClassFileUtil.java | 5 +- .../mocha/runtime/util}/package-info.java | 2 +- .../team/unnamed/mocha/util/package-info.java | 4 - .../redlance}/mocha/MochaAssertions.java | 3 +- .../mocha/runtime/ArrayAccessRuntimeTest.java | 7 +- .../mocha/runtime/BreakContinueTest.java | 3 +- .../mocha/runtime/BytecodeKotlinTest.kt | 5 +- .../mocha/runtime/CaseSensitivityTest.java | 4 +- .../redlance}/mocha/runtime/CompareTest.java | 3 +- .../mocha/runtime/ConstantValuesTest.java | 3 +- .../mocha/runtime/FibonacciTest.java | 11 +- .../redlance}/mocha/runtime/ForEachTest.java | 5 +- .../mocha/runtime/IndividualScopeTest.java | 9 +- .../runtime/InstanceMethodBindingTest.java | 5 +- .../runtime/IntCompiledFunctionTest.java | 7 +- .../mocha/runtime/ParseErrorTest.java | 5 +- .../runtime/arrow/ArrowOperatorTest.java | 10 +- .../redlance}/mocha/runtime/arrow/Player.java | 2 +- .../redlance}/mocha/runtime/arrow/World.java | 2 +- .../jvm/ArithmeticCompiledRuntimeTest.java | 8 +- .../jvm/LogicalCompiledRuntimeTest.java | 8 +- .../runtime/jvm/MathCompiledRuntimeTest.java | 8 +- .../mocha/runtime/jvm/MolangCompilerTest.java | 8 +- .../mocha/runtime/standart/MochaMathTest.java | 4 +- .../mocha/runtime/ExecutionContext.java | 6 +- .../mocha/runtime/ExpressionInliner.java | 14 +- .../mocha/runtime/ExpressionInterpreter.java | 7 +- .../mocha/runtime/IsConstantExpression.java | 12 +- .../redlance}/mocha/runtime/JavaTypes.java | 4 +- .../mocha/runtime/MolangInterpreter.java | 24 +-- .../redlance}/mocha/runtime/Scope.java | 6 +- .../redlance}/mocha/runtime/ScopeImpl.java | 8 +- .../mocha/runtime/TypeCastException.java | 2 +- .../runtime/binding/BindExternalFunction.java | 2 +- .../mocha/runtime/binding/Binding.java | 2 +- .../mocha/runtime/binding/Entity.java | 2 +- .../runtime/binding/JavaFieldBinding.java | 4 +- .../mocha/runtime/binding/JavaFunction.java | 8 +- .../runtime/binding/JavaObjectBinding.java | 12 +- .../redlance}/mocha/runtime/binding/Lazy.java | 2 +- .../runtime/binding/ReflectiveFunction.java | 18 +- .../runtime/binding/RegisteredBinding.java | 2 +- .../mocha/runtime/binding/package-info.java | 2 +- .../redlance/mocha/runtime}/package-info.java | 2 +- .../mocha/runtime/standard/MochaMath.java | 14 +- .../mocha/runtime/standard}/package-info.java | 2 +- .../util/CaseInsensitiveStringHashMap.java | 2 +- .../mocha/runtime/util/package-info.java | 4 + .../mocha/runtime/value/ArrayValue.java | 2 +- .../mocha/runtime/value/Function.java | 8 +- .../mocha/runtime/value/JavaValue.java | 2 +- .../runtime/value/MutableObjectBinding.java | 4 +- .../mocha/runtime/value/NumberValue.java | 2 +- .../mocha/runtime/value/ObjectProperty.java | 2 +- .../runtime/value/ObjectPropertyImpl.java | 2 +- .../mocha/runtime/value/ObjectValue.java | 2 +- .../mocha/runtime/value/StringValue.java | 2 +- .../redlance}/mocha/runtime/value/Value.java | 2 +- .../mocha/runtime/value/package-info.java | 4 + .../unnamed/mocha/runtime/package-info.java | 4 - .../mocha/runtime/value/package-info.java | 4 - .../team/unnamed/mocha/util/package-info.java | 4 - .../mocha/runtime/value/ValueOfTest.java | 2 +- .../CaseInsensitiveStringHashMapTest.java | 2 +- .../team/unnamed/mocha/CompareBenchmark.java | 3 +- 114 files changed, 384 insertions(+), 396 deletions(-) rename lexer/src/main/java/{team/unnamed => org/redlance}/mocha/lexer/Characters.java (98%) rename lexer/src/main/java/{team/unnamed => org/redlance}/mocha/lexer/Cursor.java (98%) rename lexer/src/main/java/{team/unnamed => org/redlance}/mocha/lexer/MolangLexer.java (99%) rename lexer/src/main/java/{team/unnamed => org/redlance}/mocha/lexer/MolangLexerImpl.java (99%) rename lexer/src/main/java/{team/unnamed => org/redlance}/mocha/lexer/Token.java (99%) rename lexer/src/main/java/{team/unnamed => org/redlance}/mocha/lexer/TokenKind.java (99%) rename lexer/src/main/java/{team/unnamed => org/redlance}/mocha/lexer/package-info.java (97%) rename lexer/src/test/java/{team/unnamed => org/redlance}/mocha/lexer/LexerTest.java (98%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/MolangParser.java (96%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/MolangParserImpl.java (98%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ParseException.java (96%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/AccessExpression.java (96%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/ArrayAccessExpression.java (97%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/BinaryExpression.java (97%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/CallExpression.java (95%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/ExecutionScopeExpression.java (95%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/Expression.java (98%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/ExpressionVisitor.java (99%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/FloatExpression.java (98%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/IdentifierExpression.java (95%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/StatementExpression.java (96%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/StringExpression.java (96%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/TernaryConditionalExpression.java (98%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/UnaryExpression.java (96%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/ast/package-info.java (97%) rename parser/src/main/java/{team/unnamed => org/redlance}/mocha/parser/package-info.java (97%) rename parser/src/main/java/{team/unnamed/mocha => org/redlance/mocha/parser}/util/ExprBytesUtils.java (96%) rename parser/src/main/java/{team/unnamed/mocha => org/redlance/mocha/parser}/util/ExpressionListUtils.java (94%) rename parser/src/main/java/{team/unnamed/mocha => org/redlance/mocha/parser}/util/network/ProtocolUtils.java (98%) rename parser/src/main/java/{team/unnamed/mocha => org/redlance/mocha/parser}/util/network/VarIntUtils.java (98%) create mode 100644 parser/src/main/java/org/redlance/mocha/parser/util/network/package-info.java rename {runtime-compiler/src/main/java/team/unnamed/mocha/runtime => parser/src/main/java/org/redlance/mocha/parser/util}/package-info.java (73%) rename parser/src/test/java/{team/unnamed => org/redlance}/mocha/parser/ArrayAccessParseTest.java (94%) rename parser/src/test/java/{team/unnamed => org/redlance}/mocha/parser/CallParseTest.java (94%) rename parser/src/test/java/{team/unnamed => org/redlance}/mocha/parser/DoubleParseTest.java (89%) rename parser/src/test/java/{team/unnamed => org/redlance}/mocha/parser/HierarchyTest.java (94%) rename parser/src/test/java/{team/unnamed => org/redlance}/mocha/parser/ParserAssertions.java (96%) rename parser/src/test/java/{team/unnamed => org/redlance}/mocha/parser/StringTest.java (96%) rename parser/src/test/java/{team/unnamed => org/redlance}/mocha/parser/TernaryParseTest.java (95%) rename runtime-compiler/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/CompileVisitResult.java (98%) rename runtime-compiler/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/FunctionCompileState.java (96%) rename runtime-compiler/src/main/java/{team/unnamed/mocha => org/redlance/mocha/runtime}/MochaEngine.java (91%) rename runtime-compiler/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/MochaFunction.java (94%) rename runtime-compiler/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/MolangCompiler.java (96%) rename runtime-compiler/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/MolangCompilingVisitor.java (97%) rename runtime-compiler/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/compiled/MochaCompiledFunction.java (96%) rename runtime-compiler/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/compiled/Named.java (97%) rename {runtime/src/main/java/team/unnamed/mocha/runtime/standard => runtime-compiler/src/main/java/org/redlance/mocha/runtime/compiled}/package-info.java (70%) rename {parser/src/main/java/team/unnamed/mocha/util => runtime-compiler/src/main/java/org/redlance/mocha/runtime}/package-info.java (75%) rename runtime-compiler/src/main/java/{team/unnamed/mocha => org/redlance/mocha/runtime}/util/ClassFileUtil.java (98%) rename {parser/src/main/java/team/unnamed/mocha/util/network => runtime-compiler/src/main/java/org/redlance/mocha/runtime/util}/package-info.java (73%) delete mode 100644 runtime-compiler/src/main/java/team/unnamed/mocha/util/package-info.java rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/MochaAssertions.java (97%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/ArrayAccessRuntimeTest.java (92%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/BreakContinueTest.java (96%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/BytecodeKotlinTest.kt (92%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/CaseSensitivityTest.java (96%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/CompareTest.java (98%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/ConstantValuesTest.java (94%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/FibonacciTest.java (92%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/ForEachTest.java (94%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/IndividualScopeTest.java (88%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/InstanceMethodBindingTest.java (93%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/IntCompiledFunctionTest.java (91%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/ParseErrorTest.java (94%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/arrow/ArrowOperatorTest.java (93%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/arrow/Player.java (97%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/arrow/World.java (96%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java (96%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java (93%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/jvm/MathCompiledRuntimeTest.java (92%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/jvm/MolangCompilerTest.java (93%) rename runtime-compiler/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/standart/MochaMathTest.java (94%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/ExecutionContext.java (91%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/ExpressionInliner.java (89%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/ExpressionInterpreter.java (99%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/IsConstantExpression.java (96%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/JavaTypes.java (97%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/MolangInterpreter.java (95%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/Scope.java (93%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/ScopeImpl.java (93%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/TypeCastException.java (97%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/binding/BindExternalFunction.java (98%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/binding/Binding.java (98%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/binding/Entity.java (97%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/binding/JavaFieldBinding.java (97%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/binding/JavaFunction.java (93%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/binding/JavaObjectBinding.java (96%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/binding/Lazy.java (96%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/binding/ReflectiveFunction.java (93%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/binding/RegisteredBinding.java (97%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/binding/package-info.java (70%) rename {runtime-compiler/src/main/java/team/unnamed/mocha => runtime/src/main/java/org/redlance/mocha/runtime}/package-info.java (75%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/standard/MochaMath.java (96%) rename {runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled => runtime/src/main/java/org/redlance/mocha/runtime/standard}/package-info.java (70%) rename runtime/src/main/java/{team/unnamed/mocha => org/redlance/mocha/runtime}/util/CaseInsensitiveStringHashMap.java (99%) create mode 100644 runtime/src/main/java/org/redlance/mocha/runtime/util/package-info.java rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/value/ArrayValue.java (98%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/value/Function.java (95%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/value/JavaValue.java (97%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/value/MutableObjectBinding.java (96%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/value/NumberValue.java (98%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/value/ObjectProperty.java (98%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/value/ObjectPropertyImpl.java (98%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/value/ObjectValue.java (98%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/value/StringValue.java (98%) rename runtime/src/main/java/{team/unnamed => org/redlance}/mocha/runtime/value/Value.java (99%) create mode 100644 runtime/src/main/java/org/redlance/mocha/runtime/value/package-info.java delete mode 100644 runtime/src/main/java/team/unnamed/mocha/runtime/package-info.java delete mode 100644 runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java delete mode 100644 runtime/src/main/java/team/unnamed/mocha/util/package-info.java rename runtime/src/test/java/{team/unnamed => org/redlance}/mocha/runtime/value/ValueOfTest.java (98%) rename runtime/src/test/java/{team/unnamed => org/redlance}/mocha/util/CaseInsensitiveStringHashMapTest.java (98%) diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/Characters.java b/lexer/src/main/java/org/redlance/mocha/lexer/Characters.java similarity index 98% rename from lexer/src/main/java/team/unnamed/mocha/lexer/Characters.java rename to lexer/src/main/java/org/redlance/mocha/lexer/Characters.java index 57981ce..ce0115e 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/Characters.java +++ b/lexer/src/main/java/org/redlance/mocha/lexer/Characters.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.lexer; +package org.redlance.mocha.lexer; import org.jetbrains.annotations.ApiStatus; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/Cursor.java b/lexer/src/main/java/org/redlance/mocha/lexer/Cursor.java similarity index 98% rename from lexer/src/main/java/team/unnamed/mocha/lexer/Cursor.java rename to lexer/src/main/java/org/redlance/mocha/lexer/Cursor.java index 6b32078..7f7684f 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/Cursor.java +++ b/lexer/src/main/java/org/redlance/mocha/lexer/Cursor.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.lexer; +package org.redlance.mocha.lexer; import org.jetbrains.annotations.NotNull; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexer.java b/lexer/src/main/java/org/redlance/mocha/lexer/MolangLexer.java similarity index 99% rename from lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexer.java rename to lexer/src/main/java/org/redlance/mocha/lexer/MolangLexer.java index 1025c0f..31b91cf 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexer.java +++ b/lexer/src/main/java/org/redlance/mocha/lexer/MolangLexer.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.lexer; +package org.redlance.mocha.lexer; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java b/lexer/src/main/java/org/redlance/mocha/lexer/MolangLexerImpl.java similarity index 99% rename from lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java rename to lexer/src/main/java/org/redlance/mocha/lexer/MolangLexerImpl.java index 83b1765..575ecd1 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/MolangLexerImpl.java +++ b/lexer/src/main/java/org/redlance/mocha/lexer/MolangLexerImpl.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.lexer; +package org.redlance.mocha.lexer; import org.jetbrains.annotations.NotNull; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/Token.java b/lexer/src/main/java/org/redlance/mocha/lexer/Token.java similarity index 99% rename from lexer/src/main/java/team/unnamed/mocha/lexer/Token.java rename to lexer/src/main/java/org/redlance/mocha/lexer/Token.java index 5d4ac9d..3efe666 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/Token.java +++ b/lexer/src/main/java/org/redlance/mocha/lexer/Token.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.lexer; +package org.redlance.mocha.lexer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/TokenKind.java b/lexer/src/main/java/org/redlance/mocha/lexer/TokenKind.java similarity index 99% rename from lexer/src/main/java/team/unnamed/mocha/lexer/TokenKind.java rename to lexer/src/main/java/org/redlance/mocha/lexer/TokenKind.java index 79fd8fb..62a8735 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/TokenKind.java +++ b/lexer/src/main/java/org/redlance/mocha/lexer/TokenKind.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.lexer; +package org.redlance.mocha.lexer; import org.jetbrains.annotations.NotNull; diff --git a/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java b/lexer/src/main/java/org/redlance/mocha/lexer/package-info.java similarity index 97% rename from lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java rename to lexer/src/main/java/org/redlance/mocha/lexer/package-info.java index c83c258..16ff1b0 100644 --- a/lexer/src/main/java/team/unnamed/mocha/lexer/package-info.java +++ b/lexer/src/main/java/org/redlance/mocha/lexer/package-info.java @@ -32,6 +32,6 @@ * @since 3.0.0 */ @ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.lexer; +package org.redlance.mocha.lexer; import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/lexer/src/test/java/team/unnamed/mocha/lexer/LexerTest.java b/lexer/src/test/java/org/redlance/mocha/lexer/LexerTest.java similarity index 98% rename from lexer/src/test/java/team/unnamed/mocha/lexer/LexerTest.java rename to lexer/src/test/java/org/redlance/mocha/lexer/LexerTest.java index 13f08f1..5066015 100644 --- a/lexer/src/test/java/team/unnamed/mocha/lexer/LexerTest.java +++ b/lexer/src/test/java/org/redlance/mocha/lexer/LexerTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.lexer; +package org.redlance.mocha.lexer; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -31,7 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -import static team.unnamed.mocha.lexer.TokenKind.*; +import static org.redlance.mocha.lexer.TokenKind.*; public class LexerTest { diff --git a/parser/src/main/java/team/unnamed/mocha/parser/MolangParser.java b/parser/src/main/java/org/redlance/mocha/parser/MolangParser.java similarity index 96% rename from parser/src/main/java/team/unnamed/mocha/parser/MolangParser.java rename to parser/src/main/java/org/redlance/mocha/parser/MolangParser.java index f88ae91..3fee7ab 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/MolangParser.java +++ b/parser/src/main/java/org/redlance/mocha/parser/MolangParser.java @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.lexer.Cursor; -import team.unnamed.mocha.lexer.MolangLexer; -import team.unnamed.mocha.lexer.TokenKind; -import team.unnamed.mocha.parser.ast.Expression; +import org.redlance.mocha.lexer.Cursor; +import org.redlance.mocha.lexer.MolangLexer; +import org.redlance.mocha.lexer.TokenKind; +import org.redlance.mocha.parser.ast.Expression; import java.io.Closeable; import java.io.IOException; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java b/parser/src/main/java/org/redlance/mocha/parser/MolangParserImpl.java similarity index 98% rename from parser/src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java rename to parser/src/main/java/org/redlance/mocha/parser/MolangParserImpl.java index 6e5f28e..1cb0651 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/MolangParserImpl.java +++ b/parser/src/main/java/org/redlance/mocha/parser/MolangParserImpl.java @@ -21,13 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.lexer.MolangLexer; -import team.unnamed.mocha.lexer.Token; -import team.unnamed.mocha.lexer.TokenKind; +import org.redlance.mocha.lexer.MolangLexer; +import org.redlance.mocha.lexer.Token; +import org.redlance.mocha.lexer.TokenKind; +import org.redlance.mocha.parser.ast.*; import team.unnamed.mocha.parser.ast.*; import java.io.IOException; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ParseException.java b/parser/src/main/java/org/redlance/mocha/parser/ParseException.java similarity index 96% rename from parser/src/main/java/team/unnamed/mocha/parser/ParseException.java rename to parser/src/main/java/org/redlance/mocha/parser/ParseException.java index 4c33ade..99b4f39 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ParseException.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ParseException.java @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.lexer.Cursor; +import org.redlance.mocha.lexer.Cursor; import java.io.IOException; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/AccessExpression.java similarity index 96% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/AccessExpression.java index ce83087..be933c4 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/AccessExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/AccessExpression.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; -import team.unnamed.mocha.util.network.ProtocolUtils; +import org.redlance.mocha.parser.util.ExprBytesUtils; +import org.redlance.mocha.parser.util.network.ProtocolUtils; import static java.util.Objects.requireNonNull; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/ArrayAccessExpression.java similarity index 97% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/ArrayAccessExpression.java index aba9a2f..146f447 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/ArrayAccessExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/ArrayAccessExpression.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.util.ExprBytesUtils; +import org.redlance.mocha.parser.util.ExprBytesUtils; import static java.util.Objects.requireNonNull; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/BinaryExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/BinaryExpression.java similarity index 97% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/BinaryExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/BinaryExpression.java index 4f8da48..6366105 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/BinaryExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/BinaryExpression.java @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; -import team.unnamed.mocha.util.network.ProtocolUtils; +import org.redlance.mocha.parser.util.ExprBytesUtils; +import org.redlance.mocha.parser.util.network.ProtocolUtils; import static java.util.Objects.requireNonNull; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/CallExpression.java similarity index 95% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/CallExpression.java index 1ecb4a5..9fe61ce 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/CallExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/CallExpression.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; -import team.unnamed.mocha.util.ExpressionListUtils; +import org.redlance.mocha.parser.util.ExprBytesUtils; +import org.redlance.mocha.parser.util.ExpressionListUtils; import java.util.List; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/ExecutionScopeExpression.java similarity index 95% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/ExecutionScopeExpression.java index 33dcb68..fb4e912 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/ExecutionScopeExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/ExecutionScopeExpression.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; -import team.unnamed.mocha.util.ExpressionListUtils; +import org.redlance.mocha.parser.util.ExprBytesUtils; +import org.redlance.mocha.parser.util.ExpressionListUtils; import java.util.List; import java.util.Objects; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/Expression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/Expression.java similarity index 98% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/Expression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/Expression.java index 75a29b4..6455afe 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/Expression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/Expression.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.ApiStatus; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java b/parser/src/main/java/org/redlance/mocha/parser/ast/ExpressionVisitor.java similarity index 99% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/ExpressionVisitor.java index d5f04bf..d976479 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/ExpressionVisitor.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/ExpressionVisitor.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import org.jetbrains.annotations.NotNull; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/FloatExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/FloatExpression.java similarity index 98% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/FloatExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/FloatExpression.java index df189c1..f7def17 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/FloatExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/FloatExpression.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/IdentifierExpression.java similarity index 95% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/IdentifierExpression.java index fcacde6..10da8ef 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/IdentifierExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/IdentifierExpression.java @@ -21,12 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; -import team.unnamed.mocha.util.network.ProtocolUtils; +import org.redlance.mocha.parser.util.network.ProtocolUtils; import java.util.Locale; import java.util.Objects; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/StatementExpression.java similarity index 96% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/StatementExpression.java index e1ebcbf..7340e8c 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/StatementExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/StatementExpression.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.network.ProtocolUtils; +import org.redlance.mocha.parser.util.network.ProtocolUtils; import java.util.Objects; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/StringExpression.java similarity index 96% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/StringExpression.java index 2eea978..246f19b 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/StringExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/StringExpression.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.network.ProtocolUtils; +import org.redlance.mocha.parser.util.network.ProtocolUtils; import java.util.Objects; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/TernaryConditionalExpression.java similarity index 98% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/TernaryConditionalExpression.java index c6ca884..61fb45f 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/TernaryConditionalExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/TernaryConditionalExpression.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; +import org.redlance.mocha.parser.util.ExprBytesUtils; import java.util.Objects; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java b/parser/src/main/java/org/redlance/mocha/parser/ast/UnaryExpression.java similarity index 96% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/UnaryExpression.java index 3635424..ad9f964 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/UnaryExpression.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/UnaryExpression.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.ExprBytesUtils; -import team.unnamed.mocha.util.network.ProtocolUtils; +import org.redlance.mocha.parser.util.ExprBytesUtils; +import org.redlance.mocha.parser.util.network.ProtocolUtils; import static java.util.Objects.requireNonNull; diff --git a/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java b/parser/src/main/java/org/redlance/mocha/parser/ast/package-info.java similarity index 97% rename from parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java rename to parser/src/main/java/org/redlance/mocha/parser/ast/package-info.java index 8215b65..34d6017 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/ast/package-info.java +++ b/parser/src/main/java/org/redlance/mocha/parser/ast/package-info.java @@ -34,6 +34,6 @@ * @since 3.0.0 */ @ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.parser.ast; +package org.redlance.mocha.parser.ast; import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/parser/package-info.java b/parser/src/main/java/org/redlance/mocha/parser/package-info.java similarity index 97% rename from parser/src/main/java/team/unnamed/mocha/parser/package-info.java rename to parser/src/main/java/org/redlance/mocha/parser/package-info.java index 841b6c5..31040c8 100644 --- a/parser/src/main/java/team/unnamed/mocha/parser/package-info.java +++ b/parser/src/main/java/org/redlance/mocha/parser/package-info.java @@ -31,6 +31,6 @@ * @since 3.0.0 */ @ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/util/ExprBytesUtils.java b/parser/src/main/java/org/redlance/mocha/parser/util/ExprBytesUtils.java similarity index 96% rename from parser/src/main/java/team/unnamed/mocha/util/ExprBytesUtils.java rename to parser/src/main/java/org/redlance/mocha/parser/util/ExprBytesUtils.java index e624595..e256584 100644 --- a/parser/src/main/java/team/unnamed/mocha/util/ExprBytesUtils.java +++ b/parser/src/main/java/org/redlance/mocha/parser/util/ExprBytesUtils.java @@ -21,12 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.util; +package org.redlance.mocha.parser.util; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; +import org.redlance.mocha.parser.ast.*; import team.unnamed.mocha.parser.ast.*; -import team.unnamed.mocha.util.network.ProtocolUtils; +import org.redlance.mocha.parser.util.network.ProtocolUtils; import java.util.HashMap; import java.util.List; diff --git a/parser/src/main/java/team/unnamed/mocha/util/ExpressionListUtils.java b/parser/src/main/java/org/redlance/mocha/parser/util/ExpressionListUtils.java similarity index 94% rename from parser/src/main/java/team/unnamed/mocha/util/ExpressionListUtils.java rename to parser/src/main/java/org/redlance/mocha/parser/util/ExpressionListUtils.java index 094d082..6e16459 100644 --- a/parser/src/main/java/team/unnamed/mocha/util/ExpressionListUtils.java +++ b/parser/src/main/java/org/redlance/mocha/parser/util/ExpressionListUtils.java @@ -21,9 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.util; +package org.redlance.mocha.parser.util; -import team.unnamed.mocha.parser.ast.Expression; +import org.redlance.mocha.parser.ast.Expression; import java.util.List; import java.util.stream.Collectors; diff --git a/parser/src/main/java/team/unnamed/mocha/util/network/ProtocolUtils.java b/parser/src/main/java/org/redlance/mocha/parser/util/network/ProtocolUtils.java similarity index 98% rename from parser/src/main/java/team/unnamed/mocha/util/network/ProtocolUtils.java rename to parser/src/main/java/org/redlance/mocha/parser/util/network/ProtocolUtils.java index 3378d07..8c05df7 100644 --- a/parser/src/main/java/team/unnamed/mocha/util/network/ProtocolUtils.java +++ b/parser/src/main/java/org/redlance/mocha/parser/util/network/ProtocolUtils.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.util.network; +package org.redlance.mocha.parser.util.network; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; diff --git a/parser/src/main/java/team/unnamed/mocha/util/network/VarIntUtils.java b/parser/src/main/java/org/redlance/mocha/parser/util/network/VarIntUtils.java similarity index 98% rename from parser/src/main/java/team/unnamed/mocha/util/network/VarIntUtils.java rename to parser/src/main/java/org/redlance/mocha/parser/util/network/VarIntUtils.java index db2a08e..6039e99 100644 --- a/parser/src/main/java/team/unnamed/mocha/util/network/VarIntUtils.java +++ b/parser/src/main/java/org/redlance/mocha/parser/util/network/VarIntUtils.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.util.network; +package org.redlance.mocha.parser.util.network; import io.netty.buffer.ByteBuf; diff --git a/parser/src/main/java/org/redlance/mocha/parser/util/network/package-info.java b/parser/src/main/java/org/redlance/mocha/parser/util/network/package-info.java new file mode 100644 index 0000000..d7eb29a --- /dev/null +++ b/parser/src/main/java/org/redlance/mocha/parser/util/network/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package org.redlance.mocha.parser.util.network; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/package-info.java b/parser/src/main/java/org/redlance/mocha/parser/util/package-info.java similarity index 73% rename from runtime-compiler/src/main/java/team/unnamed/mocha/runtime/package-info.java rename to parser/src/main/java/org/redlance/mocha/parser/util/package-info.java index d6592f6..a70bec8 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/package-info.java +++ b/parser/src/main/java/org/redlance/mocha/parser/util/package-info.java @@ -1,4 +1,4 @@ @ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.runtime; +package org.redlance.mocha.parser.util; import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java b/parser/src/test/java/org/redlance/mocha/parser/ArrayAccessParseTest.java similarity index 94% rename from parser/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java rename to parser/src/test/java/org/redlance/mocha/parser/ArrayAccessParseTest.java index fa29e14..70d8870 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/ArrayAccessParseTest.java +++ b/parser/src/test/java/org/redlance/mocha/parser/ArrayAccessParseTest.java @@ -21,15 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import org.junit.jupiter.api.Test; +import org.redlance.mocha.parser.ast.*; import team.unnamed.mocha.parser.ast.*; import java.util.Collections; -import static team.unnamed.mocha.parser.ParserAssertions.assertCreateTree; -import static team.unnamed.mocha.parser.ParserAssertions.assertParseError; +import static org.redlance.mocha.parser.ParserAssertions.assertCreateTree; +import static org.redlance.mocha.parser.ParserAssertions.assertParseError; class ArrayAccessParseTest { @Test diff --git a/parser/src/test/java/team/unnamed/mocha/parser/CallParseTest.java b/parser/src/test/java/org/redlance/mocha/parser/CallParseTest.java similarity index 94% rename from parser/src/test/java/team/unnamed/mocha/parser/CallParseTest.java rename to parser/src/test/java/org/redlance/mocha/parser/CallParseTest.java index a566d08..da4800f 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/CallParseTest.java +++ b/parser/src/test/java/org/redlance/mocha/parser/CallParseTest.java @@ -21,16 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import org.junit.jupiter.api.Test; +import org.redlance.mocha.parser.ast.*; import team.unnamed.mocha.parser.ast.*; import java.util.Arrays; import java.util.Collections; -import static team.unnamed.mocha.parser.ParserAssertions.assertCreateTree; -import static team.unnamed.mocha.parser.ParserAssertions.assertParseError; +import static org.redlance.mocha.parser.ParserAssertions.assertCreateTree; +import static org.redlance.mocha.parser.ParserAssertions.assertParseError; class CallParseTest { @Test diff --git a/parser/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java b/parser/src/test/java/org/redlance/mocha/parser/DoubleParseTest.java similarity index 89% rename from parser/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java rename to parser/src/test/java/org/redlance/mocha/parser/DoubleParseTest.java index 19c0097..32f6a21 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/DoubleParseTest.java +++ b/parser/src/test/java/org/redlance/mocha/parser/DoubleParseTest.java @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.parser.ast.FloatExpression; -import team.unnamed.mocha.parser.ast.IdentifierExpression; -import team.unnamed.mocha.parser.ast.UnaryExpression; +import org.redlance.mocha.parser.ast.FloatExpression; +import org.redlance.mocha.parser.ast.IdentifierExpression; +import org.redlance.mocha.parser.ast.UnaryExpression; -import static team.unnamed.mocha.parser.ParserAssertions.assertCreateTree; +import static org.redlance.mocha.parser.ParserAssertions.assertCreateTree; class DoubleParseTest { @Test diff --git a/parser/src/test/java/team/unnamed/mocha/parser/HierarchyTest.java b/parser/src/test/java/org/redlance/mocha/parser/HierarchyTest.java similarity index 94% rename from parser/src/test/java/team/unnamed/mocha/parser/HierarchyTest.java rename to parser/src/test/java/org/redlance/mocha/parser/HierarchyTest.java index bab591d..a404c27 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/HierarchyTest.java +++ b/parser/src/test/java/org/redlance/mocha/parser/HierarchyTest.java @@ -21,18 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.parser.ast.BinaryExpression; -import team.unnamed.mocha.parser.ast.Expression; +import org.redlance.mocha.parser.ast.BinaryExpression; +import org.redlance.mocha.parser.ast.Expression; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static team.unnamed.mocha.parser.ParserAssertions.assertCreateSameTree; -import static team.unnamed.mocha.parser.ParserAssertions.parse; +import static org.redlance.mocha.parser.ParserAssertions.assertCreateSameTree; +import static org.redlance.mocha.parser.ParserAssertions.parse; class HierarchyTest { @Test diff --git a/parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java b/parser/src/test/java/org/redlance/mocha/parser/ParserAssertions.java similarity index 96% rename from parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java rename to parser/src/test/java/org/redlance/mocha/parser/ParserAssertions.java index f137829..da70dcd 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/ParserAssertions.java +++ b/parser/src/test/java/org/redlance/mocha/parser/ParserAssertions.java @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.util.ExprBytesUtils; +import org.redlance.mocha.parser.ast.Expression; +import org.redlance.mocha.parser.util.ExprBytesUtils; import java.io.IOException; import java.io.StringReader; diff --git a/parser/src/test/java/team/unnamed/mocha/parser/StringTest.java b/parser/src/test/java/org/redlance/mocha/parser/StringTest.java similarity index 96% rename from parser/src/test/java/team/unnamed/mocha/parser/StringTest.java rename to parser/src/test/java/org/redlance/mocha/parser/StringTest.java index 9361374..6362963 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/StringTest.java +++ b/parser/src/test/java/org/redlance/mocha/parser/StringTest.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.util.ExpressionListUtils; +import org.redlance.mocha.parser.util.ExpressionListUtils; import java.io.IOException; diff --git a/parser/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java b/parser/src/test/java/org/redlance/mocha/parser/TernaryParseTest.java similarity index 95% rename from parser/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java rename to parser/src/test/java/org/redlance/mocha/parser/TernaryParseTest.java index 8b0ba57..fc50309 100644 --- a/parser/src/test/java/team/unnamed/mocha/parser/TernaryParseTest.java +++ b/parser/src/test/java/org/redlance/mocha/parser/TernaryParseTest.java @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.parser; +package org.redlance.mocha.parser; import org.junit.jupiter.api.Test; +import org.redlance.mocha.parser.ast.*; import team.unnamed.mocha.parser.ast.*; import java.util.Collections; -import static team.unnamed.mocha.parser.ParserAssertions.assertCreateTree; +import static org.redlance.mocha.parser.ParserAssertions.assertCreateTree; class TernaryParseTest { @Test diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/CompileVisitResult.java similarity index 98% rename from runtime-compiler/src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/CompileVisitResult.java index 6aa41b2..af35af5 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/CompileVisitResult.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/CompileVisitResult.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import com.google.j2objc.annotations.J2ObjCIncompatible; import org.jetbrains.annotations.Nullable; diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/FunctionCompileState.java similarity index 96% rename from runtime-compiler/src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/FunctionCompileState.java index 6e4cf59..d61f47e 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/FunctionCompileState.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/FunctionCompileState.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import com.google.j2objc.annotations.J2ObjCIncompatible; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; +import org.redlance.mocha.runtime.util.CaseInsensitiveStringHashMap; import java.lang.classfile.CodeBuilder; import java.lang.constant.ClassDesc; diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/MochaEngine.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/MochaEngine.java similarity index 91% rename from runtime-compiler/src/main/java/team/unnamed/mocha/MochaEngine.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/MochaEngine.java index 521bab6..5bb0231 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/MochaEngine.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/MochaEngine.java @@ -1,103 +1,100 @@ -/* - * This file is part of mocha, licensed under the MIT license - * - * Copyright (c) 2021-2025 Unnamed Team - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package team.unnamed.mocha; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.parser.MolangParser; -import team.unnamed.mocha.runtime.MolangCompiler; -import team.unnamed.mocha.runtime.MolangInterpreter; -import team.unnamed.mocha.runtime.Scope; - -/** - * Convenience holder that bundles a {@link MolangInterpreter} and a - * {@link MolangCompiler} sharing the same {@link Scope}. - * - *

The engine itself does not implement the parsing / interpreter / compiler - * APIs — those live on {@link MolangParser}, {@link MolangInterpreter} and - * {@link MolangCompiler}, accessed via {@link #interpreter()} and - * {@link #compiler()}. This class only exists so that callers that want both - * can construct them in one go with a shared scope.

- * - * @since 3.0.0 - */ -public final class MochaEngine { - private final MolangInterpreter interpreter; - private final MolangCompiler compiler; - - public MochaEngine(final @NotNull MolangInterpreter interpreter, final @NotNull MolangCompiler compiler) { - this.interpreter = interpreter; - this.compiler = compiler; - } - - /** - * Builds a {@link MochaEngine} on top of an existing {@link MolangInterpreter}, - * sharing its {@link Scope} and entity with a freshly created - * {@link MolangCompiler}. - * - * @since 5.0.0 - */ - @Contract("_ -> new") - public static @NotNull MochaEngine from(final @NotNull MolangInterpreter interpreter) { - return new MochaEngine<>(interpreter, new MolangCompiler(interpreter.entity(), interpreter.scope())); - } - - @Contract("_ -> new") - public static @NotNull MochaEngine create(final T entity) { - return from(MolangInterpreter.create(entity)); - } - - @Contract("-> new") - public static @NotNull MochaEngine create() { - return from(MolangInterpreter.create()); - } - - /** - * Creates a {@link MochaEngine} pre-populated with the standard - * {@code math} / {@code variable} / {@code v} bindings. - * - * @since 3.0.0 - */ - @Contract("_ -> new") - public static @NotNull MochaEngine createStandard(final T entity) { - return from(MolangInterpreter.standard(entity)); - } - - @Contract("-> new") - public static @NotNull MochaEngine createStandard() { - return from(MolangInterpreter.standard()); - } - - public @NotNull MolangInterpreter interpreter() { - return interpreter; - } - - public @NotNull MolangCompiler compiler() { - return compiler; - } - - public @NotNull Scope scope() { - return interpreter.scope(); - } -} \ No newline at end of file +/* + * This file is part of mocha, licensed under the MIT license + * + * Copyright (c) 2021-2025 Unnamed Team + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.redlance.mocha.runtime; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.redlance.mocha.parser.MolangParser; + +/** + * Convenience holder that bundles a {@link MolangInterpreter} and a + * {@link MolangCompiler} sharing the same {@link Scope}. + * + *

The engine itself does not implement the parsing / interpreter / compiler + * APIs — those live on {@link MolangParser}, {@link MolangInterpreter} and + * {@link MolangCompiler}, accessed via {@link #interpreter()} and + * {@link #compiler()}. This class only exists so that callers that want both + * can construct them in one go with a shared scope.

+ * + * @since 3.0.0 + */ +public final class MochaEngine { + private final MolangInterpreter interpreter; + private final MolangCompiler compiler; + + public MochaEngine(final @NotNull MolangInterpreter interpreter, final @NotNull MolangCompiler compiler) { + this.interpreter = interpreter; + this.compiler = compiler; + } + + /** + * Builds a {@link MochaEngine} on top of an existing {@link MolangInterpreter}, + * sharing its {@link Scope} and entity with a freshly created + * {@link MolangCompiler}. + * + * @since 5.0.0 + */ + @Contract("_ -> new") + public static @NotNull MochaEngine from(final @NotNull MolangInterpreter interpreter) { + return new MochaEngine<>(interpreter, new MolangCompiler(interpreter.entity(), interpreter.scope())); + } + + @Contract("_ -> new") + public static @NotNull MochaEngine create(final T entity) { + return from(MolangInterpreter.create(entity)); + } + + @Contract("-> new") + public static @NotNull MochaEngine create() { + return from(MolangInterpreter.create()); + } + + /** + * Creates a {@link MochaEngine} pre-populated with the standard + * {@code math} / {@code variable} / {@code v} bindings. + * + * @since 3.0.0 + */ + @Contract("_ -> new") + public static @NotNull MochaEngine createStandard(final T entity) { + return from(MolangInterpreter.standard(entity)); + } + + @Contract("-> new") + public static @NotNull MochaEngine createStandard() { + return from(MolangInterpreter.standard()); + } + + public @NotNull MolangInterpreter interpreter() { + return interpreter; + } + + public @NotNull MolangCompiler compiler() { + return compiler; + } + + public @NotNull Scope scope() { + return interpreter.scope(); + } +} diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/MochaFunction.java similarity index 94% rename from runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/MochaFunction.java index 353cbd6..92f36a5 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MochaFunction.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/MochaFunction.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import com.google.j2objc.annotations.ReflectionSupport; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; +import org.redlance.mocha.runtime.compiled.MochaCompiledFunction; /** * A {@link MochaCompiledFunction} that can be evaluated without arguments. diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/MolangCompiler.java similarity index 96% rename from runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/MolangCompiler.java index 557724f..4e15b2b 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompiler.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/MolangCompiler.java @@ -21,19 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import com.google.j2objc.annotations.J2ObjCIncompatible; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.MolangParser; -import team.unnamed.mocha.parser.ParseException; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; -import team.unnamed.mocha.runtime.compiled.Named; -import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; -import team.unnamed.mocha.util.ClassFileUtil; +import org.redlance.mocha.parser.MolangParser; +import org.redlance.mocha.parser.ParseException; +import org.redlance.mocha.parser.ast.Expression; +import org.redlance.mocha.runtime.compiled.MochaCompiledFunction; +import org.redlance.mocha.runtime.compiled.Named; +import org.redlance.mocha.runtime.util.CaseInsensitiveStringHashMap; +import org.redlance.mocha.runtime.util.ClassFileUtil; import java.io.IOException; import java.io.Reader; @@ -56,7 +56,7 @@ import java.util.function.Consumer; import static java.util.Objects.requireNonNull; -import static team.unnamed.mocha.util.ClassFileUtil.classDescOf; +import static org.redlance.mocha.runtime.util.ClassFileUtil.classDescOf; @J2ObjCIncompatible public final class MolangCompiler { diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/MolangCompilingVisitor.java similarity index 97% rename from runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/MolangCompilingVisitor.java index 970893e..7f10fb9 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/MolangCompilingVisitor.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/MolangCompilingVisitor.java @@ -21,21 +21,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import com.google.j2objc.annotations.J2ObjCIncompatible; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.parser.ast.*; -import team.unnamed.mocha.runtime.binding.Entity; -import team.unnamed.mocha.runtime.binding.JavaFieldBinding; -import team.unnamed.mocha.runtime.binding.JavaFunction; -import team.unnamed.mocha.runtime.binding.JavaObjectBinding; -import team.unnamed.mocha.runtime.value.Function; -import team.unnamed.mocha.runtime.value.NumberValue; -import team.unnamed.mocha.runtime.value.ObjectValue; -import team.unnamed.mocha.runtime.value.Value; -import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; -import team.unnamed.mocha.util.ClassFileUtil; +import org.redlance.mocha.parser.ast.*; +import org.redlance.mocha.runtime.binding.Entity; +import org.redlance.mocha.runtime.binding.JavaFieldBinding; +import org.redlance.mocha.runtime.binding.JavaFunction; +import org.redlance.mocha.runtime.binding.JavaObjectBinding; +import org.redlance.mocha.runtime.value.Function; +import org.redlance.mocha.runtime.value.NumberValue; +import org.redlance.mocha.runtime.value.ObjectValue; +import org.redlance.mocha.runtime.value.Value; +import org.redlance.mocha.runtime.util.CaseInsensitiveStringHashMap; +import org.redlance.mocha.runtime.util.ClassFileUtil; import java.lang.classfile.CodeBuilder; import java.lang.classfile.Label; @@ -51,7 +51,7 @@ import java.util.Map; import static java.lang.constant.ConstantDescs.*; -import static team.unnamed.mocha.util.ClassFileUtil.*; +import static org.redlance.mocha.runtime.util.ClassFileUtil.*; @J2ObjCIncompatible final class MolangCompilingVisitor implements ExpressionVisitor { diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/compiled/MochaCompiledFunction.java similarity index 96% rename from runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/compiled/MochaCompiledFunction.java index b854b1b..b63a609 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/MochaCompiledFunction.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/compiled/MochaCompiledFunction.java @@ -21,9 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.compiled; +package org.redlance.mocha.runtime.compiled; -import team.unnamed.mocha.runtime.MolangCompiler; +import org.redlance.mocha.runtime.MolangCompiler; /** * Marker interface for Molang compiled functions. diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/Named.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/compiled/Named.java similarity index 97% rename from runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/Named.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/compiled/Named.java index 2ad6d11..14f53ea 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/Named.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/compiled/Named.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.compiled; +package org.redlance.mocha.runtime.compiled; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/compiled/package-info.java similarity index 70% rename from runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/compiled/package-info.java index eaa9cc2..2bd9793 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/standard/package-info.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/compiled/package-info.java @@ -1,4 +1,4 @@ @ReflectionSupport(ReflectionSupport.Level.FULL) -package team.unnamed.mocha.runtime.standard; +package org.redlance.mocha.runtime.compiled; import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/parser/src/main/java/team/unnamed/mocha/util/package-info.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/package-info.java similarity index 75% rename from parser/src/main/java/team/unnamed/mocha/util/package-info.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/package-info.java index 51b43be..a7c256a 100644 --- a/parser/src/main/java/team/unnamed/mocha/util/package-info.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/package-info.java @@ -1,4 +1,4 @@ @ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.util; +package org.redlance.mocha.runtime; import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/util/ClassFileUtil.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/util/ClassFileUtil.java similarity index 98% rename from runtime-compiler/src/main/java/team/unnamed/mocha/util/ClassFileUtil.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/util/ClassFileUtil.java index 38c0559..dfce3fa 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/util/ClassFileUtil.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/util/ClassFileUtil.java @@ -21,16 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.util; +package org.redlance.mocha.runtime.util; import com.google.j2objc.annotations.J2ObjCIncompatible; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.runtime.TypeCastException; +import org.redlance.mocha.runtime.TypeCastException; import java.lang.classfile.CodeBuilder; import java.lang.classfile.Label; import java.lang.constant.ClassDesc; -import java.lang.constant.ConstantDescs; import java.lang.constant.MethodTypeDesc; import java.util.Map; import java.util.Set; diff --git a/parser/src/main/java/team/unnamed/mocha/util/network/package-info.java b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/util/package-info.java similarity index 73% rename from parser/src/main/java/team/unnamed/mocha/util/network/package-info.java rename to runtime-compiler/src/main/java/org/redlance/mocha/runtime/util/package-info.java index 10b5e8c..4c32a2a 100644 --- a/parser/src/main/java/team/unnamed/mocha/util/network/package-info.java +++ b/runtime-compiler/src/main/java/org/redlance/mocha/runtime/util/package-info.java @@ -1,4 +1,4 @@ @ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.util.network; +package org.redlance.mocha.runtime.util; import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/util/package-info.java b/runtime-compiler/src/main/java/team/unnamed/mocha/util/package-info.java deleted file mode 100644 index 51b43be..0000000 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/util/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.util; - -import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java b/runtime-compiler/src/test/java/org/redlance/mocha/MochaAssertions.java similarity index 97% rename from runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java rename to runtime-compiler/src/test/java/org/redlance/mocha/MochaAssertions.java index 3a7ecd8..4f0f52e 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/MochaAssertions.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/MochaAssertions.java @@ -21,9 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha; +package org.redlance.mocha; import org.jetbrains.annotations.NotNull; +import org.redlance.mocha.runtime.MochaEngine; import java.util.function.UnaryOperator; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ArrayAccessRuntimeTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/ArrayAccessRuntimeTest.java similarity index 92% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ArrayAccessRuntimeTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/ArrayAccessRuntimeTest.java index bf22c1a..e060b92 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ArrayAccessRuntimeTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/ArrayAccessRuntimeTest.java @@ -21,15 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.binding.Binding; +import org.redlance.mocha.runtime.binding.Binding; import java.util.function.UnaryOperator; -import static team.unnamed.mocha.MochaAssertions.assertEvaluates; +import static org.redlance.mocha.MochaAssertions.assertEvaluates; class ArrayAccessRuntimeTest { @Test diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/BreakContinueTest.java similarity index 96% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/BreakContinueTest.java index 7af0476..d9a89c4 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BreakContinueTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/BreakContinueTest.java @@ -21,10 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BytecodeKotlinTest.kt b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/BytecodeKotlinTest.kt similarity index 92% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BytecodeKotlinTest.kt rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/BytecodeKotlinTest.kt index 4a0194a..664b2ce 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/BytecodeKotlinTest.kt +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/BytecodeKotlinTest.kt @@ -1,8 +1,7 @@ -package team.unnamed.mocha.runtime +package org.redlance.mocha.runtime import org.junit.jupiter.api.Test -import team.unnamed.mocha.MochaEngine -import team.unnamed.mocha.runtime.binding.Binding +import org.redlance.mocha.runtime.binding.Binding @Binding("plain") class NoArgument(var offset: Int) { diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CaseSensitivityTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/CaseSensitivityTest.java similarity index 96% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CaseSensitivityTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/CaseSensitivityTest.java index 9a343c0..7770e2c 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CaseSensitivityTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/CaseSensitivityTest.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.junit.jupiter.api.Test; -import static team.unnamed.mocha.MochaAssertions.assertEvaluatesAndCompiles; +import static org.redlance.mocha.MochaAssertions.assertEvaluatesAndCompiles; class CaseSensitivityTest { @Test diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CompareTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/CompareTest.java similarity index 98% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CompareTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/CompareTest.java index c19c72e..2d1d72d 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/CompareTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/CompareTest.java @@ -21,11 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; import java.io.BufferedReader; import java.io.IOException; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/ConstantValuesTest.java similarity index 94% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/ConstantValuesTest.java index 042903e..c3e8ec4 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ConstantValuesTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/ConstantValuesTest.java @@ -21,10 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; class ConstantValuesTest { @Test diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/FibonacciTest.java similarity index 92% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/FibonacciTest.java index e3b2470..74de0a1 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/FibonacciTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/FibonacciTest.java @@ -21,15 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.value.Function; -import team.unnamed.mocha.runtime.value.NumberValue; -import team.unnamed.mocha.runtime.value.ObjectProperty; -import team.unnamed.mocha.runtime.value.ObjectValue; +import org.redlance.mocha.runtime.value.Function; +import org.redlance.mocha.runtime.value.NumberValue; +import org.redlance.mocha.runtime.value.ObjectProperty; +import org.redlance.mocha.runtime.value.ObjectValue; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/ForEachTest.java similarity index 94% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/ForEachTest.java index fcddaaa..d66839e 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ForEachTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/ForEachTest.java @@ -21,11 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.binding.Binding; +import org.redlance.mocha.runtime.binding.Binding; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IndividualScopeTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/IndividualScopeTest.java similarity index 88% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IndividualScopeTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/IndividualScopeTest.java index bac8fa7..93a7093 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IndividualScopeTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/IndividualScopeTest.java @@ -21,14 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.parser.ast.IdentifierExpression; -import team.unnamed.mocha.runtime.value.NumberValue; +import org.redlance.mocha.parser.ast.Expression; +import org.redlance.mocha.parser.ast.IdentifierExpression; +import org.redlance.mocha.runtime.value.NumberValue; import java.util.Collections; import java.util.List; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/InstanceMethodBindingTest.java similarity index 93% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/InstanceMethodBindingTest.java index 586bfae..fb88959 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/InstanceMethodBindingTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/InstanceMethodBindingTest.java @@ -21,11 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.binding.Binding; +import org.redlance.mocha.runtime.binding.Binding; class InstanceMethodBindingTest { @Test diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IntCompiledFunctionTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/IntCompiledFunctionTest.java similarity index 91% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IntCompiledFunctionTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/IntCompiledFunctionTest.java index a521ded..6858416 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/IntCompiledFunctionTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/IntCompiledFunctionTest.java @@ -21,12 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; -import team.unnamed.mocha.runtime.compiled.Named; +import org.redlance.mocha.runtime.compiled.MochaCompiledFunction; +import org.redlance.mocha.runtime.compiled.Named; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/ParseErrorTest.java similarity index 94% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/ParseErrorTest.java index 6894bb8..e836f48 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/ParseErrorTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/ParseErrorTest.java @@ -21,12 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.binding.Binding; +import org.redlance.mocha.runtime.binding.Binding; import java.util.ArrayList; import java.util.List; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/arrow/ArrowOperatorTest.java similarity index 93% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/arrow/ArrowOperatorTest.java index b5864c2..5f6ca91 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/ArrowOperatorTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/arrow/ArrowOperatorTest.java @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.arrow; +package org.redlance.mocha.runtime.arrow; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.binding.Binding; -import team.unnamed.mocha.runtime.binding.Entity; -import team.unnamed.mocha.runtime.value.JavaValue; +import org.redlance.mocha.runtime.MochaEngine; +import org.redlance.mocha.runtime.binding.Binding; +import org.redlance.mocha.runtime.binding.Entity; +import org.redlance.mocha.runtime.value.JavaValue; import java.util.ArrayList; import java.util.List; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/Player.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/arrow/Player.java similarity index 97% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/Player.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/arrow/Player.java index ffbdb57..fc0d654 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/Player.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/arrow/Player.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.arrow; +package org.redlance.mocha.runtime.arrow; class Player { World world; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/World.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/arrow/World.java similarity index 96% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/World.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/arrow/World.java index 988bd86..336b61c 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/arrow/World.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/arrow/World.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.arrow; +package org.redlance.mocha.runtime.arrow; class World { // 1-dimensional world Player[] entities = new Player[64]; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java similarity index 96% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java index d4a48ca..e2c8e18 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/ArithmeticCompiledRuntimeTest.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.jvm; +package org.redlance.mocha.runtime.jvm; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; -import team.unnamed.mocha.runtime.compiled.Named; +import org.redlance.mocha.runtime.MochaEngine; +import org.redlance.mocha.runtime.compiled.MochaCompiledFunction; +import org.redlance.mocha.runtime.compiled.Named; import static org.junit.jupiter.api.Assertions.*; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java similarity index 93% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java index 03b2bc8..c3a568d 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/LogicalCompiledRuntimeTest.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.jvm; +package org.redlance.mocha.runtime.jvm; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; -import team.unnamed.mocha.runtime.compiled.Named; +import org.redlance.mocha.runtime.MochaEngine; +import org.redlance.mocha.runtime.compiled.MochaCompiledFunction; +import org.redlance.mocha.runtime.compiled.Named; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/MathCompiledRuntimeTest.java similarity index 92% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/MathCompiledRuntimeTest.java index cccb96a..8b8fe9c 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MathCompiledRuntimeTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/MathCompiledRuntimeTest.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.jvm; +package org.redlance.mocha.runtime.jvm; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; -import team.unnamed.mocha.runtime.compiled.Named; +import org.redlance.mocha.runtime.MochaEngine; +import org.redlance.mocha.runtime.compiled.MochaCompiledFunction; +import org.redlance.mocha.runtime.compiled.Named; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MolangCompilerTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/MolangCompilerTest.java similarity index 93% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MolangCompilerTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/MolangCompilerTest.java index 28338e0..c193731 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/jvm/MolangCompilerTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/jvm/MolangCompilerTest.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.jvm; +package org.redlance.mocha.runtime.jvm; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; -import team.unnamed.mocha.runtime.compiled.MochaCompiledFunction; -import team.unnamed.mocha.runtime.compiled.Named; +import org.redlance.mocha.runtime.MochaEngine; +import org.redlance.mocha.runtime.compiled.MochaCompiledFunction; +import org.redlance.mocha.runtime.compiled.Named; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/standart/MochaMathTest.java b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/standart/MochaMathTest.java similarity index 94% rename from runtime-compiler/src/test/java/team/unnamed/mocha/runtime/standart/MochaMathTest.java rename to runtime-compiler/src/test/java/org/redlance/mocha/runtime/standart/MochaMathTest.java index aa96a8b..49c3926 100644 --- a/runtime-compiler/src/test/java/team/unnamed/mocha/runtime/standart/MochaMathTest.java +++ b/runtime-compiler/src/test/java/org/redlance/mocha/runtime/standart/MochaMathTest.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.standart; +package org.redlance.mocha.runtime.standart; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import team.unnamed.mocha.MochaEngine; +import org.redlance.mocha.runtime.MochaEngine; public class MochaMathTest { @Test diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java b/runtime/src/main/java/org/redlance/mocha/runtime/ExecutionContext.java similarity index 91% rename from runtime/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java rename to runtime/src/main/java/org/redlance/mocha/runtime/ExecutionContext.java index 22a0963..32bf3a4 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/ExecutionContext.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.runtime.value.Value; +import org.redlance.mocha.parser.ast.Expression; +import org.redlance.mocha.runtime.value.Value; public interface ExecutionContext { T entity(); diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java b/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInliner.java similarity index 89% rename from runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java rename to runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInliner.java index 32f33c0..5c252a0 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInliner.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInliner.java @@ -21,15 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.parser.ast.BinaryExpression; -import team.unnamed.mocha.parser.ast.CallExpression; -import team.unnamed.mocha.parser.ast.FloatExpression; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.parser.ast.ExpressionVisitor; -import team.unnamed.mocha.parser.ast.TernaryConditionalExpression; +import org.redlance.mocha.parser.ast.BinaryExpression; +import org.redlance.mocha.parser.ast.CallExpression; +import org.redlance.mocha.parser.ast.FloatExpression; +import org.redlance.mocha.parser.ast.Expression; +import org.redlance.mocha.parser.ast.ExpressionVisitor; +import org.redlance.mocha.parser.ast.TernaryConditionalExpression; import static java.util.Objects.requireNonNull; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java b/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java similarity index 99% rename from runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java rename to runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java index 757b8e8..95ea01f 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/ExpressionInterpreter.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import com.google.j2objc.annotations.LoopTranslation; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.ast.*; -import team.unnamed.mocha.runtime.binding.JavaFunction; +import org.redlance.mocha.parser.ast.*; +import org.redlance.mocha.runtime.binding.JavaFunction; +import org.redlance.mocha.runtime.value.*; import team.unnamed.mocha.runtime.value.*; import java.util.Arrays; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java b/runtime/src/main/java/org/redlance/mocha/runtime/IsConstantExpression.java similarity index 96% rename from runtime/src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java rename to runtime/src/main/java/org/redlance/mocha/runtime/IsConstantExpression.java index 6efa47e..f2eb2ae 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/IsConstantExpression.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/IsConstantExpression.java @@ -21,15 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.ast.*; -import team.unnamed.mocha.runtime.value.Function; -import team.unnamed.mocha.runtime.value.ObjectProperty; -import team.unnamed.mocha.runtime.value.ObjectValue; -import team.unnamed.mocha.runtime.value.Value; +import org.redlance.mocha.parser.ast.*; +import org.redlance.mocha.runtime.value.Function; +import org.redlance.mocha.runtime.value.ObjectProperty; +import org.redlance.mocha.runtime.value.ObjectValue; +import org.redlance.mocha.runtime.value.Value; /** * A {@link ExpressionVisitor} that determines whether an expression is diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/JavaTypes.java b/runtime/src/main/java/org/redlance/mocha/runtime/JavaTypes.java similarity index 97% rename from runtime/src/main/java/team/unnamed/mocha/runtime/JavaTypes.java rename to runtime/src/main/java/org/redlance/mocha/runtime/JavaTypes.java index 92b2fb5..ae90dcc 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/JavaTypes.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/JavaTypes.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.runtime.value.Value; +import org.redlance.mocha.runtime.value.Value; import java.util.HashMap; import java.util.Map; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java b/runtime/src/main/java/org/redlance/mocha/runtime/MolangInterpreter.java similarity index 95% rename from runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java rename to runtime/src/main/java/org/redlance/mocha/runtime/MolangInterpreter.java index 5b8ae33..4acef3e 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/MolangInterpreter.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/MolangInterpreter.java @@ -21,24 +21,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import com.google.j2objc.annotations.AutoreleasePool; import com.google.j2objc.annotations.LoopTranslation; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.MolangParser; -import team.unnamed.mocha.parser.ParseException; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.parser.ast.FloatExpression; -import team.unnamed.mocha.runtime.binding.Binding; -import team.unnamed.mocha.runtime.binding.JavaObjectBinding; -import team.unnamed.mocha.runtime.standard.MochaMath; -import team.unnamed.mocha.runtime.value.MutableObjectBinding; -import team.unnamed.mocha.runtime.value.NumberValue; -import team.unnamed.mocha.runtime.value.ObjectValue; -import team.unnamed.mocha.runtime.value.Value; +import org.redlance.mocha.parser.MolangParser; +import org.redlance.mocha.parser.ParseException; +import org.redlance.mocha.parser.ast.Expression; +import org.redlance.mocha.parser.ast.FloatExpression; +import org.redlance.mocha.runtime.binding.Binding; +import org.redlance.mocha.runtime.binding.JavaObjectBinding; +import org.redlance.mocha.runtime.standard.MochaMath; +import org.redlance.mocha.runtime.value.MutableObjectBinding; +import org.redlance.mocha.runtime.value.NumberValue; +import org.redlance.mocha.runtime.value.ObjectValue; +import org.redlance.mocha.runtime.value.Value; import java.io.IOException; import java.io.Reader; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/Scope.java b/runtime/src/main/java/org/redlance/mocha/runtime/Scope.java similarity index 93% rename from runtime/src/main/java/team/unnamed/mocha/runtime/Scope.java rename to runtime/src/main/java/org/redlance/mocha/runtime/Scope.java index 8fd7575..3020c79 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/Scope.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/Scope.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.jetbrains.annotations.NotNull; -import team.unnamed.mocha.runtime.value.ObjectValue; -import team.unnamed.mocha.runtime.value.Value; +import org.redlance.mocha.runtime.value.ObjectValue; +import org.redlance.mocha.runtime.value.Value; /** * Represents a scope, which is just a virtual object that diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java b/runtime/src/main/java/org/redlance/mocha/runtime/ScopeImpl.java similarity index 93% rename from runtime/src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java rename to runtime/src/main/java/org/redlance/mocha/runtime/ScopeImpl.java index a528454..206b43d 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/ScopeImpl.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/ScopeImpl.java @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.runtime.value.ObjectProperty; -import team.unnamed.mocha.runtime.value.Value; -import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; +import org.redlance.mocha.runtime.value.ObjectProperty; +import org.redlance.mocha.runtime.value.Value; +import org.redlance.mocha.runtime.util.CaseInsensitiveStringHashMap; import java.util.Map; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/TypeCastException.java b/runtime/src/main/java/org/redlance/mocha/runtime/TypeCastException.java similarity index 97% rename from runtime/src/main/java/team/unnamed/mocha/runtime/TypeCastException.java rename to runtime/src/main/java/org/redlance/mocha/runtime/TypeCastException.java index 7699a0e..5edbc9e 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/TypeCastException.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/TypeCastException.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime; +package org.redlance.mocha.runtime; import java.io.Serial; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java b/runtime/src/main/java/org/redlance/mocha/runtime/binding/BindExternalFunction.java similarity index 98% rename from runtime/src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java rename to runtime/src/main/java/org/redlance/mocha/runtime/binding/BindExternalFunction.java index d36f2e9..612ad18 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/BindExternalFunction.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/binding/BindExternalFunction.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.binding; +package org.redlance.mocha.runtime.binding; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Binding.java b/runtime/src/main/java/org/redlance/mocha/runtime/binding/Binding.java similarity index 98% rename from runtime/src/main/java/team/unnamed/mocha/runtime/binding/Binding.java rename to runtime/src/main/java/org/redlance/mocha/runtime/binding/Binding.java index f2b9c2d..dd30267 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Binding.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/binding/Binding.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.binding; +package org.redlance.mocha.runtime.binding; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Entity.java b/runtime/src/main/java/org/redlance/mocha/runtime/binding/Entity.java similarity index 97% rename from runtime/src/main/java/team/unnamed/mocha/runtime/binding/Entity.java rename to runtime/src/main/java/org/redlance/mocha/runtime/binding/Entity.java index 56d5759..c085f61 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Entity.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/binding/Entity.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.binding; +package org.redlance.mocha.runtime.binding; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java b/runtime/src/main/java/org/redlance/mocha/runtime/binding/JavaFieldBinding.java similarity index 97% rename from runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java rename to runtime/src/main/java/org/redlance/mocha/runtime/binding/JavaFieldBinding.java index 21c23b2..6218be0 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFieldBinding.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/binding/JavaFieldBinding.java @@ -21,12 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.binding; +package org.redlance.mocha.runtime.binding; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.runtime.value.Value; +import org.redlance.mocha.runtime.value.Value; import java.lang.reflect.Field; import java.lang.reflect.Modifier; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java b/runtime/src/main/java/org/redlance/mocha/runtime/binding/JavaFunction.java similarity index 93% rename from runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java rename to runtime/src/main/java/org/redlance/mocha/runtime/binding/JavaFunction.java index 12458f5..8abe37f 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaFunction.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/binding/JavaFunction.java @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.binding; +package org.redlance.mocha.runtime.binding; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.runtime.ExecutionContext; -import team.unnamed.mocha.runtime.value.Function; -import team.unnamed.mocha.runtime.value.Value; +import org.redlance.mocha.runtime.ExecutionContext; +import org.redlance.mocha.runtime.value.Function; +import org.redlance.mocha.runtime.value.Value; import java.lang.reflect.Method; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java b/runtime/src/main/java/org/redlance/mocha/runtime/binding/JavaObjectBinding.java similarity index 96% rename from runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java rename to runtime/src/main/java/org/redlance/mocha/runtime/binding/JavaObjectBinding.java index 730cf54..b3cc0a7 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/JavaObjectBinding.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/binding/JavaObjectBinding.java @@ -21,16 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.binding; +package org.redlance.mocha.runtime.binding; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.runtime.value.Function; -import team.unnamed.mocha.runtime.value.ObjectProperty; -import team.unnamed.mocha.runtime.value.ObjectValue; -import team.unnamed.mocha.runtime.value.Value; -import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; +import org.redlance.mocha.runtime.value.Function; +import org.redlance.mocha.runtime.value.ObjectProperty; +import org.redlance.mocha.runtime.value.ObjectValue; +import org.redlance.mocha.runtime.value.Value; +import org.redlance.mocha.runtime.util.CaseInsensitiveStringHashMap; import java.lang.reflect.Field; import java.lang.reflect.Method; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java b/runtime/src/main/java/org/redlance/mocha/runtime/binding/Lazy.java similarity index 96% rename from runtime/src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java rename to runtime/src/main/java/org/redlance/mocha/runtime/binding/Lazy.java index 06c83d1..d8cf8ff 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/Lazy.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/binding/Lazy.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.binding; +package org.redlance.mocha.runtime.binding; public interface Lazy { T get(); diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java b/runtime/src/main/java/org/redlance/mocha/runtime/binding/ReflectiveFunction.java similarity index 93% rename from runtime/src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java rename to runtime/src/main/java/org/redlance/mocha/runtime/binding/ReflectiveFunction.java index 559ea24..1d8cbe7 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/ReflectiveFunction.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/binding/ReflectiveFunction.java @@ -21,18 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.binding; +package org.redlance.mocha.runtime.binding; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.runtime.ExecutionContext; -import team.unnamed.mocha.runtime.JavaTypes; -import team.unnamed.mocha.runtime.value.ArrayValue; -import team.unnamed.mocha.runtime.value.Function; -import team.unnamed.mocha.runtime.value.JavaValue; -import team.unnamed.mocha.runtime.value.NumberValue; -import team.unnamed.mocha.runtime.value.StringValue; -import team.unnamed.mocha.runtime.value.Value; +import org.redlance.mocha.runtime.ExecutionContext; +import org.redlance.mocha.runtime.JavaTypes; +import org.redlance.mocha.runtime.value.ArrayValue; +import org.redlance.mocha.runtime.value.Function; +import org.redlance.mocha.runtime.value.JavaValue; +import org.redlance.mocha.runtime.value.NumberValue; +import org.redlance.mocha.runtime.value.StringValue; +import org.redlance.mocha.runtime.value.Value; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java b/runtime/src/main/java/org/redlance/mocha/runtime/binding/RegisteredBinding.java similarity index 97% rename from runtime/src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java rename to runtime/src/main/java/org/redlance/mocha/runtime/binding/RegisteredBinding.java index 1127949..5f8ed00 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/RegisteredBinding.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/binding/RegisteredBinding.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.binding; +package org.redlance.mocha.runtime.binding; /** * A registered binding. This is either a field or a method. diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java b/runtime/src/main/java/org/redlance/mocha/runtime/binding/package-info.java similarity index 70% rename from runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java rename to runtime/src/main/java/org/redlance/mocha/runtime/binding/package-info.java index 5a3e23a..cd195f3 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/binding/package-info.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/binding/package-info.java @@ -1,4 +1,4 @@ @ReflectionSupport(ReflectionSupport.Level.FULL) -package team.unnamed.mocha.runtime.binding; +package org.redlance.mocha.runtime.binding; import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/package-info.java b/runtime/src/main/java/org/redlance/mocha/runtime/package-info.java similarity index 75% rename from runtime-compiler/src/main/java/team/unnamed/mocha/package-info.java rename to runtime/src/main/java/org/redlance/mocha/runtime/package-info.java index d72ac74..a7c256a 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/package-info.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/package-info.java @@ -1,4 +1,4 @@ @ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha; +package org.redlance.mocha.runtime; import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/standard/MochaMath.java b/runtime/src/main/java/org/redlance/mocha/runtime/standard/MochaMath.java similarity index 96% rename from runtime/src/main/java/team/unnamed/mocha/runtime/standard/MochaMath.java rename to runtime/src/main/java/org/redlance/mocha/runtime/standard/MochaMath.java index e5a5989..ad4c2cb 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/standard/MochaMath.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/standard/MochaMath.java @@ -21,16 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.standard; +package org.redlance.mocha.runtime.standard; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.runtime.binding.BindExternalFunction; -import team.unnamed.mocha.runtime.binding.Binding; -import team.unnamed.mocha.runtime.value.NumberValue; -import team.unnamed.mocha.runtime.value.ObjectProperty; -import team.unnamed.mocha.runtime.value.ObjectValue; -import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; +import org.redlance.mocha.runtime.binding.BindExternalFunction; +import org.redlance.mocha.runtime.binding.Binding; +import org.redlance.mocha.runtime.value.NumberValue; +import org.redlance.mocha.runtime.value.ObjectProperty; +import org.redlance.mocha.runtime.value.ObjectValue; +import org.redlance.mocha.runtime.util.CaseInsensitiveStringHashMap; import java.util.Map; import java.util.Random; diff --git a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java b/runtime/src/main/java/org/redlance/mocha/runtime/standard/package-info.java similarity index 70% rename from runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java rename to runtime/src/main/java/org/redlance/mocha/runtime/standard/package-info.java index 8b81390..f8bcba3 100644 --- a/runtime-compiler/src/main/java/team/unnamed/mocha/runtime/compiled/package-info.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/standard/package-info.java @@ -1,4 +1,4 @@ @ReflectionSupport(ReflectionSupport.Level.FULL) -package team.unnamed.mocha.runtime.compiled; +package org.redlance.mocha.runtime.standard; import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java b/runtime/src/main/java/org/redlance/mocha/runtime/util/CaseInsensitiveStringHashMap.java similarity index 99% rename from runtime/src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java rename to runtime/src/main/java/org/redlance/mocha/runtime/util/CaseInsensitiveStringHashMap.java index f889299..a4b73c9 100644 --- a/runtime/src/main/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMap.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/util/CaseInsensitiveStringHashMap.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.util; +package org.redlance.mocha.runtime.util; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/org/redlance/mocha/runtime/util/package-info.java b/runtime/src/main/java/org/redlance/mocha/runtime/util/package-info.java new file mode 100644 index 0000000..4c32a2a --- /dev/null +++ b/runtime/src/main/java/org/redlance/mocha/runtime/util/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package org.redlance.mocha.runtime.util; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/ArrayValue.java similarity index 98% rename from runtime/src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java rename to runtime/src/main/java/org/redlance/mocha/runtime/value/ArrayValue.java index becd111..f041976 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ArrayValue.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/ArrayValue.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/Function.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/Function.java similarity index 95% rename from runtime/src/main/java/team/unnamed/mocha/runtime/value/Function.java rename to runtime/src/main/java/org/redlance/mocha/runtime/value/Function.java index 8adb65b..756c31d 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/Function.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/Function.java @@ -21,13 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.parser.ast.Expression; -import team.unnamed.mocha.runtime.ExecutionContext; -import team.unnamed.mocha.runtime.ExpressionInterpreter; +import org.redlance.mocha.parser.ast.Expression; +import org.redlance.mocha.runtime.ExecutionContext; +import org.redlance.mocha.runtime.ExpressionInterpreter; /** * Represents a Molang function. Receives a certain amount of diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/JavaValue.java similarity index 97% rename from runtime/src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java rename to runtime/src/main/java/org/redlance/mocha/runtime/value/JavaValue.java index d92aa16..bff2c70 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/JavaValue.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/JavaValue.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; public final class JavaValue implements Value { private final Object value; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/MutableObjectBinding.java similarity index 96% rename from runtime/src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java rename to runtime/src/main/java/org/redlance/mocha/runtime/value/MutableObjectBinding.java index 8a0802b..d340dad 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/MutableObjectBinding.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/MutableObjectBinding.java @@ -21,11 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import team.unnamed.mocha.util.CaseInsensitiveStringHashMap; +import org.redlance.mocha.runtime.util.CaseInsensitiveStringHashMap; import java.util.Map; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/NumberValue.java similarity index 98% rename from runtime/src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java rename to runtime/src/main/java/org/redlance/mocha/runtime/value/NumberValue.java index 65a80d4..aa7b00b 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/NumberValue.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/NumberValue.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/ObjectProperty.java similarity index 98% rename from runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java rename to runtime/src/main/java/org/redlance/mocha/runtime/value/ObjectProperty.java index 77e0d1b..cb80f0e 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectProperty.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/ObjectProperty.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/ObjectPropertyImpl.java similarity index 98% rename from runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java rename to runtime/src/main/java/org/redlance/mocha/runtime/value/ObjectPropertyImpl.java index a189ff3..b157267 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectPropertyImpl.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/ObjectPropertyImpl.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/ObjectValue.java similarity index 98% rename from runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java rename to runtime/src/main/java/org/redlance/mocha/runtime/value/ObjectValue.java index 2f787b3..06930e1 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/ObjectValue.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/ObjectValue.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/StringValue.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/StringValue.java similarity index 98% rename from runtime/src/main/java/team/unnamed/mocha/runtime/value/StringValue.java rename to runtime/src/main/java/org/redlance/mocha/runtime/value/StringValue.java index e6ae66b..5c52412 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/StringValue.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/StringValue.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/Value.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/Value.java similarity index 99% rename from runtime/src/main/java/team/unnamed/mocha/runtime/value/Value.java rename to runtime/src/main/java/org/redlance/mocha/runtime/value/Value.java index a6f3488..b9301b7 100644 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/Value.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/Value.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; diff --git a/runtime/src/main/java/org/redlance/mocha/runtime/value/package-info.java b/runtime/src/main/java/org/redlance/mocha/runtime/value/package-info.java new file mode 100644 index 0000000..b1cc491 --- /dev/null +++ b/runtime/src/main/java/org/redlance/mocha/runtime/value/package-info.java @@ -0,0 +1,4 @@ +@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) +package org.redlance.mocha.runtime.value; + +import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/package-info.java b/runtime/src/main/java/team/unnamed/mocha/runtime/package-info.java deleted file mode 100644 index d6592f6..0000000 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.runtime; - -import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java b/runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java deleted file mode 100644 index 7700369..0000000 --- a/runtime/src/main/java/team/unnamed/mocha/runtime/value/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.runtime.value; - -import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/main/java/team/unnamed/mocha/util/package-info.java b/runtime/src/main/java/team/unnamed/mocha/util/package-info.java deleted file mode 100644 index 51b43be..0000000 --- a/runtime/src/main/java/team/unnamed/mocha/util/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@ReflectionSupport(ReflectionSupport.Level.NATIVE_ONLY) -package team.unnamed.mocha.util; - -import com.google.j2objc.annotations.ReflectionSupport; \ No newline at end of file diff --git a/runtime/src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java b/runtime/src/test/java/org/redlance/mocha/runtime/value/ValueOfTest.java similarity index 98% rename from runtime/src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java rename to runtime/src/test/java/org/redlance/mocha/runtime/value/ValueOfTest.java index 5f39f84..7d34219 100644 --- a/runtime/src/test/java/team/unnamed/mocha/runtime/value/ValueOfTest.java +++ b/runtime/src/test/java/org/redlance/mocha/runtime/value/ValueOfTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.runtime.value; +package org.redlance.mocha.runtime.value; import org.junit.jupiter.api.Test; diff --git a/runtime/src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java b/runtime/src/test/java/org/redlance/mocha/util/CaseInsensitiveStringHashMapTest.java similarity index 98% rename from runtime/src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java rename to runtime/src/test/java/org/redlance/mocha/util/CaseInsensitiveStringHashMapTest.java index 8328853..8b7de54 100644 --- a/runtime/src/test/java/team/unnamed/mocha/util/CaseInsensitiveStringHashMapTest.java +++ b/runtime/src/test/java/org/redlance/mocha/util/CaseInsensitiveStringHashMapTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package team.unnamed.mocha.util; +package org.redlance.mocha.util; import org.junit.jupiter.api.Test; diff --git a/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java b/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java index 0bc72c4..cc598e1 100644 --- a/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java +++ b/src/jmh/java/team/unnamed/mocha/CompareBenchmark.java @@ -42,7 +42,8 @@ import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import team.unnamed.mocha.runtime.MochaFunction; +import org.redlance.mocha.runtime.MochaEngine; +import org.redlance.mocha.runtime.MochaFunction; import java.util.List; import java.util.concurrent.TimeUnit; From 4bfed8ee0a2db41cba69af6f615b5ef7f9551aec Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Tue, 12 May 2026 00:41:15 +0700 Subject: [PATCH 09/15] oops --- .../main/java/org/redlance/mocha/parser/MolangParserImpl.java | 1 - .../main/java/org/redlance/mocha/parser/util/ExprBytesUtils.java | 1 - .../java/org/redlance/mocha/runtime/ExpressionInterpreter.java | 1 - 3 files changed, 3 deletions(-) diff --git a/parser/src/main/java/org/redlance/mocha/parser/MolangParserImpl.java b/parser/src/main/java/org/redlance/mocha/parser/MolangParserImpl.java index 1cb0651..cb1ddd2 100644 --- a/parser/src/main/java/org/redlance/mocha/parser/MolangParserImpl.java +++ b/parser/src/main/java/org/redlance/mocha/parser/MolangParserImpl.java @@ -29,7 +29,6 @@ import org.redlance.mocha.lexer.Token; import org.redlance.mocha.lexer.TokenKind; import org.redlance.mocha.parser.ast.*; -import team.unnamed.mocha.parser.ast.*; import java.io.IOException; import java.util.ArrayList; diff --git a/parser/src/main/java/org/redlance/mocha/parser/util/ExprBytesUtils.java b/parser/src/main/java/org/redlance/mocha/parser/util/ExprBytesUtils.java index e256584..1457b1d 100644 --- a/parser/src/main/java/org/redlance/mocha/parser/util/ExprBytesUtils.java +++ b/parser/src/main/java/org/redlance/mocha/parser/util/ExprBytesUtils.java @@ -26,7 +26,6 @@ import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; import org.redlance.mocha.parser.ast.*; -import team.unnamed.mocha.parser.ast.*; import org.redlance.mocha.parser.util.network.ProtocolUtils; import java.util.HashMap; diff --git a/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java b/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java index 95ea01f..d0b0260 100644 --- a/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java @@ -30,7 +30,6 @@ import org.redlance.mocha.parser.ast.*; import org.redlance.mocha.runtime.binding.JavaFunction; import org.redlance.mocha.runtime.value.*; -import team.unnamed.mocha.runtime.value.*; import java.util.Arrays; import java.util.List; From 83c7be1c5722415035de58243b67bcf8c5b5e62d Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Wed, 13 May 2026 23:17:03 +0700 Subject: [PATCH 10/15] Update CaseInsensitiveStringHashMap.java --- .../mocha/runtime/util/CaseInsensitiveStringHashMap.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/src/main/java/org/redlance/mocha/runtime/util/CaseInsensitiveStringHashMap.java b/runtime/src/main/java/org/redlance/mocha/runtime/util/CaseInsensitiveStringHashMap.java index a4b73c9..e972c86 100644 --- a/runtime/src/main/java/org/redlance/mocha/runtime/util/CaseInsensitiveStringHashMap.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/util/CaseInsensitiveStringHashMap.java @@ -73,6 +73,7 @@ private static T lowercase(T key) { } private static Map lowercaseMap(Map m) { + if (m instanceof CaseInsensitiveStringHashMap) return m; final Map lowercased = new HashMap<>(); for (Entry entry : m.entrySet()) { lowercased.put(lowercase(entry.getKey()), entry.getValue()); @@ -97,6 +98,7 @@ public V put(String key, V value) { @Override public void putAll(Map m) { + if (m == this) return; super.putAll(lowercaseMap(m)); } From f25c353997de87808815bc7600e9f483c0855edb Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sun, 17 May 2026 02:27:08 +0700 Subject: [PATCH 11/15] Add maven meta --- build.gradle | 35 ++++++++++++++++++++++++++++++++++- gradle.properties | 2 +- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 86f0552..35524d8 100644 --- a/build.gradle +++ b/build.gradle @@ -74,9 +74,42 @@ subprojects { } publications { maven(MavenPublication) { - groupId = "com.zigythebird.mochafloats" + groupId = "org.redlance.mochafloats" artifactId = project.name version = project.version + + pom { + name = "MochaFloats ${project.name}" + description = "A lightweight, fast and efficient Molang lexer, parser, interpreter and compiler" + url = "https://github.com/PlayerAnimationLibrary/mochafloats" + + developers { + developer { + id = "dima_dencep" + name = "dima_dencep" + email = "dima_dencep@redlance.org" + } + developer { + id = "zigythebird" + name = "ZigyTheBird" + email = "imanyarandi222@gmail.com" + } + } + + licenses { + license { + name = "MIT" + url = "https://github.com/PlayerAnimationLibrary/mochafloats/blob/HEAD/license.txt" + } + } + + scm { + connection = "scm:git:github.com/PlayerAnimationLibrary/mochafloats.git" + developerConnection = "scm:git:github.com/PlayerAnimationLibrary/mochafloats.git" + url = "https://github.com/PlayerAnimationLibrary/mochafloats.git" + } + } + from components.java } } diff --git a/gradle.properties b/gradle.properties index 1c7d8b0..fb6a72c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ group=team.unnamed -version=6.0.0 +version=1.0.0 description=A lightweight, fast and efficient Molang lexer, parser, interpreter and compiler for Java 24+ kotlin.stdlib.default.dependency=false \ No newline at end of file From 766d176ad98254e2999362fc28c31daaa4f73d59 Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sun, 17 May 2026 03:16:08 +0700 Subject: [PATCH 12/15] Remove unnecessary --- .../org/redlance/mocha/runtime/ExpressionInterpreter.java | 5 ++--- .../java/org/redlance/mocha/runtime/MolangInterpreter.java | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java b/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java index d0b0260..084da29 100644 --- a/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/ExpressionInterpreter.java @@ -23,7 +23,6 @@ */ package org.redlance.mocha.runtime; -import com.google.j2objc.annotations.LoopTranslation; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -278,7 +277,7 @@ public T entity() { if (expr instanceof Function) { final Function callable = (Function) expr; - for (@LoopTranslation(LoopTranslation.LoopStyle.FAST_ENUMERATION) final Value val : arrayIterable) { + for (final Value val : arrayIterable) { // set 'val' as current value // eval (objectExpr.propertyName = val) final Value evaluatedObjectValue = this.eval(objectExpr); @@ -318,7 +317,7 @@ public T entity() { public @NotNull Value visitExecutionScope(final @NotNull ExecutionScopeExpression executionScope) { List expressions = executionScope.expressions(); return (Function) (context, arguments) -> { - for (@LoopTranslation(LoopTranslation.LoopStyle.FAST_ENUMERATION) Expression expression : expressions) { + for (Expression expression : expressions) { // eval expression, ignore result context.eval(expression); diff --git a/runtime/src/main/java/org/redlance/mocha/runtime/MolangInterpreter.java b/runtime/src/main/java/org/redlance/mocha/runtime/MolangInterpreter.java index 4acef3e..1f001d4 100644 --- a/runtime/src/main/java/org/redlance/mocha/runtime/MolangInterpreter.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/MolangInterpreter.java @@ -24,7 +24,6 @@ package org.redlance.mocha.runtime; import com.google.j2objc.annotations.AutoreleasePool; -import com.google.j2objc.annotations.LoopTranslation; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -164,7 +163,7 @@ public float eval(final @NotNull List expressions, final @Nullable C evaluator.warnOnReflectiveFunctionUsage(warnOnReflectiveFunctionUsage); Value lastResult = NumberValue.zero(); - for (@LoopTranslation(LoopTranslation.LoopStyle.FAST_ENUMERATION) final Expression expression : expressions) { + for (final Expression expression : expressions) { lastResult = expression.visit(evaluator); final Value returnValue = evaluator.popReturnValue(); if (returnValue != null) { From e771e966d5f64a4914984e4062c9d820ede8e3ab Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sun, 17 May 2026 03:17:40 +0700 Subject: [PATCH 13/15] Add AutoreleasePool --- .../java/org/redlance/mocha/runtime/IsConstantExpression.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/src/main/java/org/redlance/mocha/runtime/IsConstantExpression.java b/runtime/src/main/java/org/redlance/mocha/runtime/IsConstantExpression.java index f2eb2ae..4d76216 100644 --- a/runtime/src/main/java/org/redlance/mocha/runtime/IsConstantExpression.java +++ b/runtime/src/main/java/org/redlance/mocha/runtime/IsConstantExpression.java @@ -23,6 +23,7 @@ */ package org.redlance.mocha.runtime; +import com.google.j2objc.annotations.AutoreleasePool; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.redlance.mocha.parser.ast.*; @@ -48,10 +49,12 @@ private IsConstantExpression(final @Nullable Scope scope) { this.scope = scope; } + @AutoreleasePool public static boolean test(final @NotNull Expression expression) { return expression.visit(INSTANCE); } + @AutoreleasePool public static boolean test(final @NotNull Expression expression, final @NotNull Scope scope) { return expression.visit(new IsConstantExpression(scope)); } From c335b1c3778124e61e2d5ce7aa2635625f93d053 Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sun, 17 May 2026 03:17:52 +0700 Subject: [PATCH 14/15] Fix tests --- .../java/org/redlance/mocha/parser/ArrayAccessParseTest.java | 1 - .../src/test/java/org/redlance/mocha/parser/CallParseTest.java | 1 - .../test/java/org/redlance/mocha/parser/TernaryParseTest.java | 1 - .../redlance/mocha/util/CaseInsensitiveStringHashMapTest.java | 1 + 4 files changed, 1 insertion(+), 3 deletions(-) diff --git a/parser/src/test/java/org/redlance/mocha/parser/ArrayAccessParseTest.java b/parser/src/test/java/org/redlance/mocha/parser/ArrayAccessParseTest.java index 70d8870..dd6a289 100644 --- a/parser/src/test/java/org/redlance/mocha/parser/ArrayAccessParseTest.java +++ b/parser/src/test/java/org/redlance/mocha/parser/ArrayAccessParseTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.redlance.mocha.parser.ast.*; -import team.unnamed.mocha.parser.ast.*; import java.util.Collections; diff --git a/parser/src/test/java/org/redlance/mocha/parser/CallParseTest.java b/parser/src/test/java/org/redlance/mocha/parser/CallParseTest.java index da4800f..07e9391 100644 --- a/parser/src/test/java/org/redlance/mocha/parser/CallParseTest.java +++ b/parser/src/test/java/org/redlance/mocha/parser/CallParseTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.redlance.mocha.parser.ast.*; -import team.unnamed.mocha.parser.ast.*; import java.util.Arrays; import java.util.Collections; diff --git a/parser/src/test/java/org/redlance/mocha/parser/TernaryParseTest.java b/parser/src/test/java/org/redlance/mocha/parser/TernaryParseTest.java index fc50309..55c1972 100644 --- a/parser/src/test/java/org/redlance/mocha/parser/TernaryParseTest.java +++ b/parser/src/test/java/org/redlance/mocha/parser/TernaryParseTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.redlance.mocha.parser.ast.*; -import team.unnamed.mocha.parser.ast.*; import java.util.Collections; diff --git a/runtime/src/test/java/org/redlance/mocha/util/CaseInsensitiveStringHashMapTest.java b/runtime/src/test/java/org/redlance/mocha/util/CaseInsensitiveStringHashMapTest.java index 8b7de54..f2cf00f 100644 --- a/runtime/src/test/java/org/redlance/mocha/util/CaseInsensitiveStringHashMapTest.java +++ b/runtime/src/test/java/org/redlance/mocha/util/CaseInsensitiveStringHashMapTest.java @@ -24,6 +24,7 @@ package org.redlance.mocha.util; import org.junit.jupiter.api.Test; +import org.redlance.mocha.runtime.util.CaseInsensitiveStringHashMap; import java.util.Arrays; import java.util.HashSet; From 42d930048aa0e283512da64510a2c33e621d4c66 Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Tue, 30 Jun 2026 03:14:33 +0700 Subject: [PATCH 15/15] Update build.gradle --- parser/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser/build.gradle b/parser/build.gradle index 59f8a14..ec30b60 100644 --- a/parser/build.gradle +++ b/parser/build.gradle @@ -1,4 +1,4 @@ dependencies { api project(":lexer") - api "io.netty:netty-buffer:4.2.13.Final" + api "io.netty:netty-buffer:4.2.15.Final" }