/** Transfers variables from one interpreter's bindings to another. */ private void copyBindings(final ScriptInterpreter src, final ScriptInterpreter dest) { if (src == null) return; // nothing to copy final Bindings srcBindings = src.getBindings(); final Bindings destBindings = dest.getBindings(); for (final String key : src.getBindings().keySet()) { final Object value = src.getLanguage().decode(srcBindings.get(key)); destBindings.put(key, value); } }
/** * Evaluates the line, including handling of special colon-prefixed REPL commands. * * @param line The line to evaluate. * @return False iff the REPL should exit. */ public boolean evaluate(final String line) { try { final String tLine = line.trim(); if (tLine.equals(":help")) help(); else if (tLine.equals(":vars")) vars(); else if (tLine.equals(":langs")) langs(); else if (tLine.equals(":debug")) debug(); else if (tLine.startsWith(":lang ")) lang(line.substring(6).trim()); else if (tLine.equals(":quit")) return false; else { // ensure that a script language is active if (interpreter == null) return true; // pass the input to the current interpreter for evaluation final Object result = interpreter.interpret(line); if (result != ScriptInterpreter.MORE_INPUT_PENDING) { out.println(s(result)); } } } catch (final ScriptException exc) { // NB: Something went wrong interpreting the line of code. // Let's just display the error message, unless we are in debug mode. if (debug) exc.printStackTrace(out); else { final String msg = exc.getMessage(); out.println(msg == null ? exc.getClass().getName() : msg); } } catch (final Throwable exc) { // NB: Something unusual went wrong. Dump the whole exception always. exc.printStackTrace(out); } return true; }
/** * Creates a new {@link ScriptInterpreter} to interpret statements, preserving existing variables * from the previous interpreter. * * @param langName The script language of the new interpreter. * @throws IllegalArgumentException if the requested language is not available. */ public void lang(final String langName) { // create the new interpreter final ScriptLanguage language = scriptService.getLanguageByName(langName); if (language == null) { out.println("No such language: " + langName); return; } final ScriptInterpreter newInterpreter = new DefaultScriptInterpreter(language); // preserve state of the previous interpreter try { copyBindings(interpreter, newInterpreter); } catch (final Throwable t) { t.printStackTrace(out); } out.println("language -> " + newInterpreter.getLanguage().getLanguageName()); interpreter = newInterpreter; }
/** Lists variables in the script context. */ public void vars() { if (interpreter == null) return; // no active script language final List<String> keys = new ArrayList<>(); final List<Object> types = new ArrayList<>(); final Bindings bindings = interpreter.getBindings(); for (final String key : bindings.keySet()) { final Object value = bindings.get(key); keys.add(key); types.add(type(value)); } printColumns(keys, types); }
/** Outputs a greeting, and sets up the initial language of the REPL. */ public void initialize() { out.println("Welcome to the SciJava REPL!"); out.println(); help(); final List<ScriptLanguage> langs = getInterpretedLanguages(); if (langs.isEmpty()) { out.println("--------------------------------------------------------------"); out.println("Uh oh! There are no SciJava script languages available!"); out.println("Are any on your classpath? E.g.: org.scijava:scripting-groovy?"); out.println("--------------------------------------------------------------"); out.println(); return; } out.println("Have fun!"); out.println(); lang(langs.get(0).getLanguageName()); populateBindings(interpreter.getBindings()); }
private String type(final Object value) { if (value == null) return NULL; final Object decoded = interpreter.getLanguage().decode(value); if (decoded == null) return NULL; return "[" + decoded.getClass().getName() + "]"; }
/** Outputs the prompt. */ public void prompt() { out.print(interpreter == null || interpreter.isReady() ? "> " : "\\ "); }