diff --git a/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java b/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java index 32f2f16..60b739d 100644 --- a/src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java +++ b/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-2023 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-2023 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; @@ -31,4 +31,8 @@ public interface ExecutionContext { T entity(); @Nullable Object eval(final @NotNull Expression expression); + + @Nullable Object flag(); + + void flag(final @Nullable Object flag); } diff --git a/src/main/java/team/unnamed/mocha/runtime/ExpressionEvaluatorImpl.java b/src/main/java/team/unnamed/mocha/runtime/ExpressionEvaluatorImpl.java index 1e6dfc7..c44486d 100644 --- a/src/main/java/team/unnamed/mocha/runtime/ExpressionEvaluatorImpl.java +++ b/src/main/java/team/unnamed/mocha/runtime/ExpressionEvaluatorImpl.java @@ -148,6 +148,16 @@ private static Evaluator arithmetic(ArithmeticOperator op) { )); } + @Override + public @Nullable Object flag() { + return flag; + } + + @Override + public void flag(final @Nullable Object flag) { + this.flag = flag; + } + @Override public T entity() { return entity; @@ -204,13 +214,14 @@ public T entity() { // - double: How many times should we loop // - CallableBinding: The looped expressions int n = Math.round((float) args.next().eval().getAsNumber()); - Object expr = args.next().eval(); + Value expr = args.next().eval(); if (expr instanceof Function) { final Function callable = (Function) expr; for (int i = 0; i < n; i++) { - Object value = callable.evaluate(this); - if (value == StatementExpression.Op.BREAK) { + final ExpressionEvaluator evaluatorThisCall = createChild(); + callable.evaluate(evaluatorThisCall); + if (evaluatorThisCall.flag() == StatementExpression.Op.BREAK) { break; } // (not necessary, callable already exits when returnValue @@ -283,16 +294,14 @@ public T entity() { @Override public @NotNull Value visitExecutionScope(final @NotNull ExecutionScopeExpression executionScope) { List expressions = executionScope.expressions(); - ExpressionEvaluator evaluatorForThisScope = createChild(); return (Function) (context, arguments) -> { for (Expression expression : expressions) { // eval expression, ignore result - expression.visit(evaluatorForThisScope); + context.eval(expression); // check for return values - final Value returnValue = evaluatorForThisScope.popReturnValue(); - if (returnValue != null) { - return returnValue; + if (context.flag() != null) { + break; } } return NumberValue.zero();