From 86ab465538825520b4f9c24b222fc74d83a5e089 Mon Sep 17 00:00:00 2001 From: Florian Angerer <florian.angerer@oracle.com> Date: Tue, 13 Mar 2018 11:47:56 +0100 Subject: [PATCH] Create proper file source if file option provided. --- .../engine/shell/EmbeddedConsoleHandler.java | 10 ++++- .../truffle/r/launcher/ConsoleHandler.java | 5 +++ .../r/launcher/DefaultConsoleHandler.java | 7 +++ .../r/launcher/JLineConsoleHandler.java | 7 +++ .../oracle/truffle/r/launcher/RCommand.java | 5 +-- .../r/launcher/StringConsoleHandler.java | 5 +++ .../truffle/r/parser/ParserGeneration.java | 3 +- .../src/com/oracle/truffle/r/parser/R.g | 45 ++++++++++++++++++- 8 files changed, 81 insertions(+), 6 deletions(-) diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/EmbeddedConsoleHandler.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/EmbeddedConsoleHandler.java index 4af701bbec..a6fa46db30 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/EmbeddedConsoleHandler.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/EmbeddedConsoleHandler.java @@ -59,6 +59,7 @@ public final class EmbeddedConsoleHandler extends DelegatingConsoleHandler { private Context context; private Supplier<ConsoleHandler> delegateFactory; private ConsoleHandler delegate; + private int currentLine; private CallTarget readLineCallTarget; private CallTarget writeCallTarget; @@ -78,7 +79,9 @@ public final class EmbeddedConsoleHandler extends DelegatingConsoleHandler { @Override public String readLine() { try (ContextClose ignored = inContext()) { - return isOverridden("R_ReadConsole") ? (String) getReadLineCallTarget().call("TODO prompt>") : getDelegate().readLine(); + String l = isOverridden("R_ReadConsole") ? (String) getReadLineCallTarget().call("TODO prompt>") : getDelegate().readLine(); + currentLine++; + return l; } } @@ -239,4 +242,9 @@ public final class EmbeddedConsoleHandler extends DelegatingConsoleHandler { return null; } } + + @Override + public int getCurrentLineIndex() { + return currentLine; + } } diff --git a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/ConsoleHandler.java b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/ConsoleHandler.java index f83c933b57..844b268bb1 100644 --- a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/ConsoleHandler.java +++ b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/ConsoleHandler.java @@ -39,6 +39,11 @@ public abstract class ConsoleHandler { */ public abstract String readLine(); + /** + * Return the current 1-based line number. + */ + public abstract int getCurrentLineIndex(); + /** * Set the R prompt. */ diff --git a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/DefaultConsoleHandler.java b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/DefaultConsoleHandler.java index a395a0e613..b9c839a4b2 100644 --- a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/DefaultConsoleHandler.java +++ b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/DefaultConsoleHandler.java @@ -35,6 +35,7 @@ public class DefaultConsoleHandler extends ConsoleHandler { private final BufferedReader in; private final PrintStream out; private String prompt; + private int currentLine; public DefaultConsoleHandler(InputStream in, OutputStream out, boolean interactive) { this.in = new BufferedReader(new InputStreamReader(in)); @@ -49,6 +50,7 @@ public class DefaultConsoleHandler extends ConsoleHandler { out.print(prompt); } String line = in.readLine(); + currentLine++; if ((line == null || "".equals(line.trim())) && prompt != null && !interactive) { out.println(); } @@ -62,4 +64,9 @@ public class DefaultConsoleHandler extends ConsoleHandler { public void setPrompt(String prompt) { this.prompt = prompt; } + + @Override + public int getCurrentLineIndex() { + return currentLine; + } } diff --git a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/JLineConsoleHandler.java b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/JLineConsoleHandler.java index e3c4cee27e..f8b7771733 100644 --- a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/JLineConsoleHandler.java +++ b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/JLineConsoleHandler.java @@ -38,6 +38,7 @@ public class JLineConsoleHandler extends ConsoleHandler { private final ConsoleReader console; private final MemoryHistory history; private final boolean noPrompt; + private int currentLine; public JLineConsoleHandler(InputStream inStream, OutputStream outStream, boolean noPrompt) { this.noPrompt = noPrompt; @@ -65,6 +66,7 @@ public class JLineConsoleHandler extends ConsoleHandler { public String readLine() { try { console.getTerminal().init(); + currentLine++; return console.readLine(); } catch (UserInterruptException e) { // interrupted by ctrl-c @@ -94,4 +96,9 @@ public class JLineConsoleHandler extends ConsoleHandler { } return result; } + + @Override + public int getCurrentLineIndex() { + return currentLine; + } } diff --git a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RCommand.java b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RCommand.java index 22b5346499..4fd6c52a0f 100644 --- a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RCommand.java +++ b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RCommand.java @@ -262,7 +262,6 @@ public class RCommand { */ public static int readEvalPrint(Context context, ConsoleHandler consoleHandler, File srcFile) { int lastStatus = 0; - int line = 0; try { while (true) { // processing inputs boolean doEcho = doEcho(context); @@ -272,7 +271,6 @@ public class RCommand { if (input == null) { throw new EOFException(); } - line++; String trInput = input.trim(); if (trInput.equals("") || trInput.charAt(0) == '#') { // nothing to parse @@ -281,12 +279,13 @@ public class RCommand { String continuePrompt = null; StringBuilder sb = new StringBuilder(input); + int startLine = consoleHandler.getCurrentLineIndex(); while (true) { // processing subsequent lines while input is incomplete lastStatus = 0; try { Source src; if (srcFile != null) { - src = Source.newBuilder("R", sb.toString(), srcFile.getName() + "#" + line).interactive(true).uri(srcFile.toURI()).buildLiteral(); + src = Source.newBuilder("R", sb.toString(), srcFile.getName() + "#" + startLine).interactive(true).uri(srcFile.toURI()).buildLiteral(); } else { src = Source.newBuilder("R", sb.toString(), "<REPL>").interactive(true).buildLiteral(); } diff --git a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/StringConsoleHandler.java b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/StringConsoleHandler.java index 1327a81629..87561dd086 100644 --- a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/StringConsoleHandler.java +++ b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/StringConsoleHandler.java @@ -54,4 +54,9 @@ class StringConsoleHandler extends ConsoleHandler { public void setPrompt(String prompt) { this.prompt = prompt; } + + @Override + public int getCurrentLineIndex() { + return currentLine; + } } diff --git a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ParserGeneration.java b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ParserGeneration.java index 0aaa94d549..cca68a741b 100644 --- a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ParserGeneration.java +++ b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ParserGeneration.java @@ -96,6 +96,7 @@ public class ParserGeneration { "handle four and more dots as identifier", "allow greek characters in identifiers", "allow everything but newlines in %<ident>% operators", - "allow strings in :: and :::" + "allow strings in :: and :::", + "use file for interactive single-line source" }; } diff --git a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/R.g b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/R.g index 439c593195..2d26c76179 100644 --- a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/R.g +++ b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/R.g @@ -28,6 +28,7 @@ package com.oracle.truffle.r.parser; import java.util.ArrayList; import java.util.List; +import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -37,6 +38,7 @@ import java.net.URISyntaxException; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.source.Source.Builder; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.runtime.RError; @@ -78,10 +80,51 @@ import com.oracle.truffle.r.runtime.RError; public RParser(Source source, RCodeBuilder<T> builder, TruffleRLanguage language) { super(new CommonTokenStream(new RLexer(new ANTLRStringStream(source.getCharacters().toString())))); assert source != null && builder != null; - this.source = source; this.initialSource = source; this.builder = builder; this.language = language; + if (source.getURI() != null && source.getName().contains("#")) { + this.source = createFullSource(source); + } else { + this.source = source; + } + } + + private Source createFullSource(Source original) { + String originalName = original.getName(); + + // check if source name is like 'path/to/source.R#45-54' + int hash_idx = originalName.lastIndexOf("#"); + if (hash_idx == -1) { + return original; + } + + String fileName = originalName.substring(0, hash_idx); + String lineRange = originalName.substring(hash_idx + 1); + + try { + // check for line range, e.g. '45-54' + int startLine = -1; + int endLine = -1; + int dashIdx = lineRange.indexOf('-'); + if (dashIdx != -1) { + startLine = Integer.parseInt(lineRange.substring(0, dashIdx)); + endLine = Integer.parseInt(lineRange.substring(dashIdx + 1)); + } else { + startLine = Integer.parseInt(lineRange); + } + Builder<IOException, RuntimeException, RuntimeException> newBuilder = Source.newBuilder(new File(fileName)); + if (original.isInteractive()) { + newBuilder.interactive(); + } + Source fullSource = newBuilder.build(); + fileStartOffset = -fullSource.getLineStartOffset(startLine); + return fullSource; + } catch (NumberFormatException e) { + } catch (IOException e) { + } catch (RuntimeException e) { + } + return original; } /** -- GitLab