Skip to content

Commit

Permalink
fix(interpreter): use a separate field for 'break' and 'continue' flags
Browse files Browse the repository at this point in the history
  • Loading branch information
yusshu committed Dec 26, 2023
1 parent 61c7a93 commit ad226d6
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 32 deletions.
52 changes: 28 additions & 24 deletions src/main/java/team/unnamed/mocha/runtime/ExecutionContext.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -31,4 +31,8 @@ public interface ExecutionContext<T> {
T entity();

@Nullable Object eval(final @NotNull Expression expression);

@Nullable Object flag();

void flag(final @Nullable Object flag);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<T> callable = (Function<T>) expr;
for (int i = 0; i < n; i++) {
Object value = callable.evaluate(this);
if (value == StatementExpression.Op.BREAK) {
final ExpressionEvaluator<T> evaluatorThisCall = createChild();
callable.evaluate(evaluatorThisCall);
if (evaluatorThisCall.flag() == StatementExpression.Op.BREAK) {
break;
}
// (not necessary, callable already exits when returnValue
Expand Down Expand Up @@ -283,16 +294,14 @@ public T entity() {
@Override
public @NotNull Value visitExecutionScope(final @NotNull ExecutionScopeExpression executionScope) {
List<Expression> expressions = executionScope.expressions();
ExpressionEvaluator<T> evaluatorForThisScope = createChild();
return (Function<T>) (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();
Expand Down

0 comments on commit ad226d6

Please sign in to comment.