docs: public static void processSource(Context cx, String filename)
              throws IOException
      {
          if (filename == null || filename.equals("-")) {
              Scriptable scope = getShellScope();
              Charset cs;
              String charEnc = shellContextFactory.getCharacterEncoding();
              if (charEnc != null) {
                  cs = Charset.forName(charEnc);
              } else {
                  cs = Charset.defaultCharset();
              }
              ShellConsole console = global.getConsole(cs);
              if (filename == null) {
                  // print implementation version
                  console.println(cx.getImplementationVersion());
              }
  
              int lineno = 1;
              boolean hitEOF = false;
              while (!hitEOF) {
                  String[] prompts = global.getPrompts(cx);
                  String prompt = null;
                  if (filename == null)
                      prompt = prompts[0];
                  console.flush();
                  String source = "";
  
                  // Collect lines of source to compile.
                  while (true) {
                      String newline;
                      try {
                          newline = console.readLine(prompt);
                      }
                      catch (IOException ioe) {
                          console.println(ioe.toString());
                          break;
                      }
                      if (newline == null) {
                          hitEOF = true;
                          break;
                      }
                      source = source + newline + "\n";
                      lineno++;
                      if (cx.stringIsCompilableUnit(source))
                          break;
                      prompt = prompts[1];
                  }
                  try {
                      Script script = cx.compileString(source, "<stdin>", lineno, null);
                      if (script != null) {
                          Object result = script.exec(cx, scope);
                          // Avoid printing out undefined or function definitions.
                          if (result != Context.getUndefinedValue() &&
                                  !(result instanceof Function &&
                                          source.trim().startsWith("function")))
                          {
                              try {
                                  console.println(Context.toString(result));
                              } catch (RhinoException rex) {
                                  ToolErrorReporter.reportException(
                                          cx.getErrorReporter(), rex);
                              }
                          }
                          NativeArray h = global.history;
                          h.put((int)h.getLength(), h, source);
                      }
                  } catch (RhinoException rex) {
                      ToolErrorReporter.reportException(
                          cx.getErrorReporter(), rex);
                      exitCode = EXITCODE_RUNTIME_ERROR;
                  } catch (VirtualMachineError ex) {
                      // Treat StackOverflow and OutOfMemory as runtime errors
                      ex.printStackTrace();
                      String msg = ToolErrorReporter.getMessage(
                          "msg.uncaughtJSException", ex.toString());
                      Context.reportError(msg);
                      exitCode = EXITCODE_RUNTIME_ERROR;
                  }
              }
              console.println();
              console.flush();
          } else if (useRequire && filename.equals(mainModule)) {
              require.requireMain(cx, filename);
          } else {
              processFile(cx, getScope(filename), filename);
          }
      }