From 2646974358636cdde89bfc42b6820701900685bc Mon Sep 17 00:00:00 2001 From: Tijs van der Storm Date: Wed, 17 Feb 2021 13:57:33 +0100 Subject: [PATCH] Delayed starting of terminal to allow sending commands to it. --- src/org/rascalmpl/library/util/REPL.rsc | 23 +++++- src/org/rascalmpl/library/util/TermREPL.java | 85 ++++++++++++++++++-- 2 files changed, 101 insertions(+), 7 deletions(-) diff --git a/src/org/rascalmpl/library/util/REPL.rsc b/src/org/rascalmpl/library/util/REPL.rsc index 97e2b8f16c9..40c06d8734a 100644 --- a/src/org/rascalmpl/library/util/REPL.rsc +++ b/src/org/rascalmpl/library/util/REPL.rsc @@ -21,8 +21,11 @@ private Content echo(str line) = text(line); private Completion noSuggestions(str _, int _) = <0, []>; +alias Terminal = tuple[void() run, void(str) send]; + @javaClass{org.rascalmpl.library.util.TermREPL} -java void startREPL(REPL repl, +@reflect{Makes closures} +java Terminal newREPL(REPL repl, // filling in defaults from the repl constructor, for use in the Java code: str title = repl.title, @@ -33,3 +36,21 @@ java void startREPL(REPL repl, Content (str ) handler = repl.handler, Completion(str , int) completor = repl.completor, str () stacktrace = repl.stacktrace); + +void startREPL(REPL repl, + + // filling in defaults from the repl constructor, for use in the Java code: + str title = repl.title, + str welcome = repl.welcome, + str prompt = repl.prompt, + str quit = repl.quit, + loc history = repl.history, + Content (str ) handler = repl.handler, + Completion(str , int) completor = repl.completor, + str () stacktrace = repl.stacktrace) { + + Terminal tm = newREPL(repl, title=title, welcome=welcome, + prompt=prompt, quit=quit, history=history, + handler=handler, completor=completor, stacktrace=stacktrace); + tm.run(); +} diff --git a/src/org/rascalmpl/library/util/TermREPL.java b/src/org/rascalmpl/library/util/TermREPL.java index 3756de1c35f..0d00e5d350d 100644 --- a/src/org/rascalmpl/library/util/TermREPL.java +++ b/src/org/rascalmpl/library/util/TermREPL.java @@ -8,15 +8,23 @@ import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; import java.nio.charset.Charset; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Function; import org.rascalmpl.exceptions.RuntimeExceptionFactory; import org.rascalmpl.interpreter.Evaluator; +import org.rascalmpl.interpreter.IEvaluatorContext; +import org.rascalmpl.interpreter.control_exceptions.MatchFailed; +import org.rascalmpl.interpreter.env.Environment; import org.rascalmpl.interpreter.result.AbstractFunction; +import org.rascalmpl.interpreter.result.ICallableValue; +import org.rascalmpl.interpreter.result.Result; +import org.rascalmpl.interpreter.result.ResultFactory; import org.rascalmpl.library.lang.json.io.JsonValueWriter; import org.rascalmpl.repl.BaseREPL; import org.rascalmpl.repl.CompletionResult; @@ -57,14 +65,79 @@ public TermREPL(IValueFactory vf, OutputStream out, OutputStream err, InputStrea this.in = in; } - public void startREPL(IConstructor repl, IString title, IString welcome, IString prompt, IString quit, - ISourceLocation history, IFunction handler, IFunction completor, IFunction stacktrace) { + public ITuple newREPL(IConstructor repl, IString title, IString welcome, IString prompt, IString quit, + ISourceLocation history, IFunction handler, IFunction completor, IFunction stacktrace, IEvaluatorContext eval) { + lang = new TheREPL(vf, title, welcome, prompt, quit, history, handler, completor, stacktrace, in, err, out); + BaseREPL baseRepl; try { - lang = new TheREPL(vf, title, welcome, prompt, quit, history, handler, completor, stacktrace, in, err, out); - new BaseREPL(lang, null, in, err, out, true, true, history, TerminalFactory.get(), null).run(); - } catch (Throwable e) { - e.printStackTrace(new PrintWriter(err)); + baseRepl = new BaseREPL(lang, null, in, err, out, true, true, history, TerminalFactory.get(), null); } + catch (Throwable e) { + throw RuntimeExceptionFactory.io(e.getMessage()); + } + + TypeFactory tf = TypeFactory.getInstance(); + IFunction send = new AbstractFunction(null, eval.getEvaluator(), + tf.functionType(tf.voidType(), tf.tupleType(tf.stringType()), tf.tupleEmpty()), + tf.functionType(tf.voidType(), tf.tupleType(tf.stringType()), tf.tupleEmpty()), + Collections.emptyList(), false, eval.getEvaluator().getCurrentEnvt()) { + + @Override + public Result call(Type[] argTypes, IValue[] argValues, Map keyArgValues) throws MatchFailed { + baseRepl.queueCommand(((IString)argValues[0]).getValue()); + return ResultFactory.nothing(); + } + + @Override + public ICallableValue cloneInto(Environment env) { + return this; + } + + @Override + public boolean isStatic() { + return false; + } + + @Override + public boolean isDefault() { + return false; + } + }; + + IFunction run = new AbstractFunction(null, eval.getEvaluator(), + tf.functionType(tf.voidType(), tf.tupleEmpty(), tf.tupleEmpty()), + tf.functionType(tf.voidType(), tf.tupleEmpty(), tf.tupleEmpty()), + Collections.emptyList(), false, eval.getEvaluator().getCurrentEnvt()) { + + + @Override + public Result call(Type[] argTypes, IValue[] argValues, Map keyArgValues) throws MatchFailed { + try { + baseRepl.run(); + } + catch (IOException e) { + throw RuntimeExceptionFactory.io(e.getMessage()); + } + return ResultFactory.nothing(); + } + + @Override + public boolean isStatic() { + return false; + } + + @Override + public ICallableValue cloneInto(Environment env) { + return this; + } + + @Override + public boolean isDefault() { + return false; + } + }; + + return vf.tuple(run, send); } public static class TheREPL implements ILanguageProtocol {