package org.metaborg.spoofax.shell.client.console.strategies;

import org.metaborg.core.MetaborgException;
import org.metaborg.core.context.IContext;
import org.metaborg.spoofax.core.stratego.IStrategoCommon;
import org.metaborg.spoofax.core.terms.ITermFactoryService;
import org.metaborg.spoofax.shell.core.IEvaluationStrategy;
import org.spoofax.interpreter.core.Tools;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.spoofax.interpreter.terms.ITermFactory;

import com.google.inject.Inject;

public class StrategoEvaluationStrategy implements IEvaluationStrategy {

	// TODO: hardcoded init and eval terms
	private static final String INIT_TERM = "shell_init";
	private static final String EVAL_TERM = "shell_eval";

	private final IStrategoCommon strategoCommon;
	private final ITermFactory termFactory;

	/**
	 * We keep track of a global environment.
	 * It is expected to be passed along all eval iterations.
	 */
	private IStrategoTerm env;

	@Inject
	public StrategoEvaluationStrategy(IStrategoCommon strategoCommon,
			ITermFactoryService termFactoryService) {
		this.strategoCommon = strategoCommon;
		this.termFactory = termFactoryService.getGeneric();
	}

	@Override
	public String name() {
		return "stratego";
	}

	@Override
	public IStrategoTerm evaluate(IStrategoTerm term, IContext context) throws MetaborgException {
		// initialize the environment
		if (env == null) {
			env = strategoCommon.invoke(context.language(), context, term, INIT_TERM);
		}

		IStrategoTerm result = strategoCommon.invoke(context.language(), context,
				termFactory.makeTuple(term, env), EVAL_TERM);

		if (Tools.isTermTuple(result)) {
			int subterms = result.getSubtermCount();
			if (subterms == 2) {
				IStrategoTerm newEnv = result.getSubterm(1);
				IStrategoTerm value = result.getSubterm(0);
				env = newEnv;
				return value;
			} else {
				throw new MetaborgException(String.format(
						"Evaluation result expected: Tuple of 2. Found: Tuple of %d", subterms));
			}
		} else {
			// TODO give useful 'found' if possible
			throw new MetaborgException(
					String.format("Evaluation result expected: Tuple. Found: %s",
							"<result.getTermType()=" + result.getTermType() + ">"));
		}

	}

}

@@ -503,16 +503,89 @@
 nject;%0A%0A
+%0A/**%0A * An %7B@link IEvaluationStrategy%7D for Stratego-based languages.%0A */%0A
 public c
@@ -1031,16 +1031,448 @@
 m env;%0A%0A
+%09/**%0A%09 * Construct a new %7B@link StrategoEvaluationStrategy%7D.%0A%09 * On the first %7B@link #evaluate(IStrategoTerm, IContext) call an%0A%09 * environment is initialised and subsequent calls will use this%0A%09 * envirnonment.%0A%09 *%0A%09 * @param strategoCommon%0A%09 *            The interface for all Statego related functionality.%0A%09 * @param termFactoryService%0A%09 *            The %7B@link ITermFactoryService%7D for retrieving an %7B@link ITermFactory%7D.%0A%09 */%0A
 %09@Inject

Add javadoc