Skip to content

Commit

Permalink
Add StrategoRuntime invokeOrNull, tryInvoke methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Virtlink committed Sep 26, 2021
1 parent 2c4bee7 commit c7ed510
Showing 1 changed file with 143 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package mb.stratego.common;

import mb.common.util.ListView;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spoofax.interpreter.core.Interpreter;
import org.spoofax.interpreter.core.InterpreterException;
import org.spoofax.interpreter.terms.IStrategoAppl;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.spoofax.interpreter.terms.ITermFactory;
import org.strategoxt.HybridInterpreter;

import java.util.Optional;

public class StrategoRuntime {
private final HybridInterpreter hybridInterpreter;
private final StrategoIOAgent ioAgent;
Expand Down Expand Up @@ -40,49 +43,160 @@ public StrategoRuntime(StrategoRuntime other, StrategoIOAgent ioAgent, Adaptable
this(other.hybridInterpreter, ioAgent, contextObject);
}


/**
* Invokes a Stratego strategy with no term arguments,
* throwing {@link StrategoException} if the strategy fails.
*
* @param strategy the name of the strategy to invoke
* @param input the input term
* @return the resulting term
* @throws StrategoException if the strategy or its invocation failed
*/
public IStrategoTerm invoke(String strategy, IStrategoTerm input) throws StrategoException {
@Nullable final IStrategoTerm result = invokeOrNull(strategy, input);
if (result == null)
throw StrategoException.strategyFail(strategy, input, hybridInterpreter.getCompiledContext().getTrace());
return result;
}

/**
* Invokes a Stratego strategy with the specified term arguments,
* throwing {@link StrategoException} if the strategy fails.
*
* @param strategy the name of the strategy to invoke
* @param input the input term
* @param arguments the term arguments
* @return the resulting term
* @throws StrategoException if the strategy or its invocation failed
*/
public IStrategoTerm invoke(String strategy, IStrategoTerm input, ListView<IStrategoTerm> arguments) throws StrategoException {
@Nullable final IStrategoTerm result = invokeOrNull(strategy, input, arguments);
if (result == null)
throw StrategoException.strategyFail(strategy, input, hybridInterpreter.getCompiledContext().getTrace());
return result;
}

/**
* Invokes a Stratego strategy with the specified term arguments,
* throwing {@link StrategoException} if the strategy fails.
*
* @param strategy the name of the strategy to invoke
* @param input the input term
* @param arguments the term arguments
* @return the resulting term
* @throws StrategoException if the strategy or its invocation failed
*/
public IStrategoTerm invoke(String strategy, IStrategoTerm input, IStrategoTerm... arguments) throws StrategoException {
@Nullable final IStrategoTerm result = invokeOrNull(strategy, input, arguments);
if (result == null)
throw StrategoException.strategyFail(strategy, input, hybridInterpreter.getCompiledContext().getTrace());
return result;
}

/**
* Invokes a Stratego strategy with no term arguments,
* returning {@link Optional#empty()} if the strategy fails.
*
* @param strategy the name of the strategy to invoke
* @param input the input term
* @return an {@link Optional} with the resulting term; or {@link Optional#empty()} if the strategy failed
* @throws StrategoException if the strategy invocation failed
*/
public Optional<IStrategoTerm> tryInvoke(String strategy, IStrategoTerm input) throws StrategoException {
return Optional.ofNullable(invokeOrNull(strategy, input));
}

/**
* Invokes a Stratego strategy with the specified term arguments,
* returning {@link Optional#empty()} if the strategy fails.
*
* @param strategy the name of the strategy to invoke
* @param input the input term
* @param arguments the term arguments
* @return an {@link Optional} with the resulting term; or {@link Optional#empty()} if the strategy failed
* @throws StrategoException if the strategy invocation failed
*/
public Optional<IStrategoTerm> tryInvoke(String strategy, IStrategoTerm input, ListView<IStrategoTerm> arguments) throws StrategoException {
return Optional.ofNullable(invokeOrNull(strategy, input, arguments));
}

/**
* Invokes a Stratego strategy with the specified term arguments,
* returning {@link Optional#empty()} if the strategy fails.
*
* @param strategy the name of the strategy to invoke
* @param input the input term
* @param arguments the term arguments
* @return an {@link Optional} with the resulting term; or {@link Optional#empty()} if the strategy failed
* @throws StrategoException if the strategy invocation failed
*/
public Optional<IStrategoTerm> tryInvoke(String strategy, IStrategoTerm input, IStrategoTerm... arguments) throws StrategoException {
return Optional.ofNullable(invokeOrNull(strategy, input, arguments));
}

/**
* Invokes a Stratego strategy with no term arguments,
* returning {@code null} if the strategy fails.
*
* @param strategy the name of the strategy to invoke
* @param input the input term
* @return the resulting term; or {@code null} if the strategy failed
* @throws StrategoException if the strategy invocation failed
*/
public @Nullable IStrategoTerm invokeOrNull(String strategy, IStrategoTerm input) throws StrategoException {
return invokeOrNull(strategy, input, ListView.of());
}

/**
* Invokes a Stratego strategy with the specified term arguments,
* returning {@code null} if the strategy fails.
*
* @param strategy the name of the strategy to invoke
* @param input the input term
* @param arguments the term arguments
* @return the resulting term; or {@code null} if the strategy failed
* @throws StrategoException if the strategy invocation failed
*/
public @Nullable IStrategoTerm invokeOrNull(String strategy, IStrategoTerm input, ListView<IStrategoTerm> arguments) throws StrategoException {
hybridInterpreter.setCurrent(input);
hybridInterpreter.setIOAgent(ioAgent);
hybridInterpreter.getContext().setContextObject(contextObject);
hybridInterpreter.getCompiledContext().setContextObject(contextObject);
try {
final boolean success = hybridInterpreter.invoke(strategy);
if(!success) {
throw StrategoException.strategyFail(strategy, input, hybridInterpreter.getCompiledContext().getTrace());
}
return hybridInterpreter.current();
} catch(InterpreterException e) {
throw StrategoException.fromInterpreterException(strategy, input, hybridInterpreter.getCompiledContext().getTrace(), e);
}
}

public IStrategoTerm invoke(String strategy, IStrategoTerm input, ListView<IStrategoTerm> termArguments) throws StrategoException {
hybridInterpreter.setCurrent(input);
hybridInterpreter.setIOAgent(ioAgent);
hybridInterpreter.getContext().setContextObject(contextObject);
hybridInterpreter.getCompiledContext().setContextObject(contextObject);
ITermFactory termFactory = getTermFactory();
IStrategoTerm strategyName = termFactory.makeString(Interpreter.cify(strategy) + "_0_" + termArguments.size());
IStrategoTerm strategyNameTerm = termFactory.makeAppl("SVar", strategyName);
IStrategoAppl strategyCallTerm = termFactory.makeAppl(
"CallT",
strategyNameTerm,
termFactory.makeList(),
termFactory.makeList(termArguments.asUnmodifiable())
);
try {
final boolean success = hybridInterpreter.evaluate(strategyCallTerm);
if(!success) {
throw StrategoException.strategyFail(strategy, input, hybridInterpreter.getCompiledContext().getTrace());
final boolean success;
if (arguments.isEmpty()) {
success = hybridInterpreter.invoke(strategy);
} else {
ITermFactory termFactory = getTermFactory();
IStrategoTerm strategyName = termFactory.makeString(Interpreter.cify(strategy) + "_0_" + arguments.size());
IStrategoTerm strategyNameTerm = termFactory.makeAppl("SVar", strategyName);
IStrategoAppl strategyCallTerm = termFactory.makeAppl(
"CallT",
strategyNameTerm,
termFactory.makeList(),
termFactory.makeList(arguments.asUnmodifiable())
);
success = hybridInterpreter.evaluate(strategyCallTerm);
}
if(!success) return null;
return hybridInterpreter.current();
} catch(InterpreterException e) {
throw StrategoException.fromInterpreterException(strategy, input, hybridInterpreter.getCompiledContext().getTrace(), e);
}
}

public IStrategoTerm invoke(String strategy, IStrategoTerm input, IStrategoTerm... arguments) throws StrategoException {
/**
* Invokes a Stratego strategy with the specified term arguments,
* returning {@code null} if the strategy fails.
*
* @param strategy the name of the strategy to invoke
* @param input the input term
* @param arguments the term arguments
* @return the resulting term; or {@code null} if the strategy failed
* @throws StrategoException if the strategy invocation failed
*/
public @Nullable IStrategoTerm invokeOrNull(String strategy, IStrategoTerm input, IStrategoTerm... arguments) throws StrategoException {
return invoke(strategy, input, ListView.of(arguments));
}

Expand Down

0 comments on commit c7ed510

Please sign in to comment.