All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.qlexpress4.runtime.instruction.WhileInstruction Maven / Gradle / Ivy

package com.alibaba.qlexpress4.runtime.instruction;

import com.alibaba.qlexpress4.QLOptions;
import com.alibaba.qlexpress4.exception.ErrorReporter;
import com.alibaba.qlexpress4.exception.QLErrorCodes;
import com.alibaba.qlexpress4.runtime.*;
import com.alibaba.qlexpress4.runtime.scope.QvmBlockScope;
import com.alibaba.qlexpress4.runtime.util.ThrowUtils;
import com.alibaba.qlexpress4.utils.PrintlnUtils;

import java.util.Collections;
import java.util.HashMap;
import java.util.function.Consumer;

/**
 * Operation: while (condition) do body
 * Input: 0
 * Output: 0
 * 

* Author: DQinYuan */ public class WhileInstruction extends QLInstruction { private final QLambdaDefinition condition; private final QLambdaDefinition body; private final int whileScopeMaxStackSize; public WhileInstruction(ErrorReporter errorReporter, QLambdaDefinition condition, QLambdaDefinition body, int whileScopeMaxStackSize) { super(errorReporter); this.condition = condition; this.body = body; this.whileScopeMaxStackSize = whileScopeMaxStackSize; } @Override public QResult execute(QContext qContext, QLOptions qlOptions) { DelegateQContext whileScopeContext = new DelegateQContext(qContext, new QvmBlockScope(qContext, Collections.emptyMap(), whileScopeMaxStackSize, ExceptionTable.EMPTY)); QLambda conditionLambda = condition.toLambda(whileScopeContext, qlOptions, false); QLambda bodyLambda = body.toLambda(whileScopeContext, qlOptions, true); whileBody: while (evalCondition(conditionLambda)) { try { QResult bodyResult = bodyLambda.call(); switch (bodyResult.getResultType()) { case RETURN: return bodyResult; case BREAK: break whileBody; } } catch (Throwable t) { throw ThrowUtils.wrapThrowable(t, errorReporter, "WHILE_BODY_EXECUTE_ERROR", "while body execute error"); } } return QResult.NEXT_INSTRUCTION; } @Override public int stackInput() { return 0; } @Override public int stackOutput() { return 0; } @Override public void println(int index, int depth, Consumer debug) { PrintlnUtils.printlnByCurDepth(depth, index + ": While", debug); PrintlnUtils.printlnByCurDepth(depth+1, "Condition", debug); condition.println(depth+2, debug); PrintlnUtils.printlnByCurDepth(depth+1, "Body", debug); body.println(depth+2, debug); } private boolean evalCondition(QLambda conditionLambda) { try { Object conditionResult = conditionLambda.call().getResult().get(); if (!(conditionResult instanceof Boolean)) { throw errorReporter.report(QLErrorCodes.WHILE_CONDITION_BOOL_REQUIRED.name(), QLErrorCodes.WHILE_CONDITION_BOOL_REQUIRED.getErrorMsg()); } return (boolean) conditionResult; } catch (Throwable t) { throw ThrowUtils.wrapThrowable(t, errorReporter, QLErrorCodes.WHILE_CONDITION_ERROR.name(), QLErrorCodes.WHILE_CONDITION_ERROR.getErrorMsg()); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy