From 4686a2d6f69da3925e84a2f10410d3bab607d0b1 Mon Sep 17 00:00:00 2001 From: paltherr Date: Thu, 15 May 2003 14:36:17 +0000 Subject: - Split class Interpreter into classes Interpre... - Split class Interpreter into classes Interpreter and InterpreterShell --- config/list/interpreter.lst | 1 + sources/scala/tools/scalai/Evaluator.java | 8 + sources/scala/tools/scalai/Interpreter.java | 442 +-------------------- sources/scala/tools/scalai/InterpreterShell.java | 475 +++++++++++++++++++++++ sources/scala/tools/scalai/Main.java | 4 +- 5 files changed, 505 insertions(+), 425 deletions(-) create mode 100644 sources/scala/tools/scalai/InterpreterShell.java diff --git a/config/list/interpreter.lst b/config/list/interpreter.lst index b52d5af696..d752e0f599 100644 --- a/config/list/interpreter.lst +++ b/config/list/interpreter.lst @@ -20,6 +20,7 @@ ExpressionContext.java Function.java Interpreter.java InterpreterCommand.java +InterpreterShell.java JavaMirror.java Main.java Override.java diff --git a/sources/scala/tools/scalai/Evaluator.java b/sources/scala/tools/scalai/Evaluator.java index 9e5b98f6d8..ea69e27880 100644 --- a/sources/scala/tools/scalai/Evaluator.java +++ b/sources/scala/tools/scalai/Evaluator.java @@ -76,6 +76,14 @@ public class Evaluator { //######################################################################## // Public Methods + public Object toString(Object object) { + try { + return object.toString(); + } catch (Throwable exception) { + return throw_(exception); + } + } + public Object evaluate(CodeContainer code) { return evaluate(code, null, new Object[0]); } diff --git a/sources/scala/tools/scalai/Interpreter.java b/sources/scala/tools/scalai/Interpreter.java index 17f2bbeb04..4c61cfc5cb 100644 --- a/sources/scala/tools/scalai/Interpreter.java +++ b/sources/scala/tools/scalai/Interpreter.java @@ -9,266 +9,48 @@ package scalai; -import java.io.StringReader; -import java.io.PushbackReader; -import java.io.InputStreamReader; -import java.io.BufferedReader; -import java.io.PrintWriter; -import java.io.IOException; -import java.util.List; -import java.util.ArrayList; +import scalac.Global; import scala.runtime.InterpreterSupport; -import scala.runtime.InterpreterSupport.DefinitionPrinter; import scala.runtime.InterpreterSupport.EvaluationResult; -import scalac.Global; -import scalac.ast.parser.Sourcefile; -import scalac.util.PrefixMatcher; -import scalac.util.Strings; -import scalac.util.Debug; - public class Interpreter { - //######################################################################## - // Public Constants - - public static final String PRODUCT = Main.PRODUCT; - public static final String VERSION = Main.VERSION; - public static final String COPYRIGHT = "(c) 2002, LAMP/EPFL"; - - //######################################################################## - // Private Constants - - private static final int QUIT = 0; - private static final int LOAD = 1; - private static final int USE = 2; - private static final int GC = 3; - private static final int MEMORY = 4; - private static final int SHOWVER = 5; - private static final int HELP = 6; - //######################################################################## // Private Fields private final Global global; - private final boolean interactive; - private final boolean emacs; - private final BufferedReader reader; - private final PrintWriter writer; - private final PrefixMatcher matcher; - private final Evaluator evaluator; private final Compiler compiler; - - private String[] lfiles; - private String[] ufiles; - - //######################################################################## - // Protected Methods - - protected PrefixMatcher matcher() { - PrefixMatcher matcher = new PrefixMatcher(); - matcher.insert(":quit", new Integer(QUIT), - "Quit interpreter"); - matcher.insert(":load", new Integer(LOAD), "", - "Load files (or repeat last use if no files are given)"); - matcher.insert(":use", new Integer(USE), "", - "Use files (or repeat last use if no files are given)"); - matcher.insert(":gc", new Integer(GC), - "Run garbage collector"); - matcher.insert(":memory", new Integer(MEMORY), - "Print out memory usage"); - matcher.insert(":help", new Integer(HELP), - "Print out this command summary"); - matcher.insert(":version", new Integer(SHOWVER), - "Print out product version"); - matcher.insert(":?", new Integer(HELP), - "Same as :help"); - return matcher; - } + private final Evaluator evaluator; //######################################################################## // Public Constructors - public Interpreter(InterpreterCommand command) { - this(command, new BufferedReader(new InputStreamReader(System.in)), - new PrintWriter(System.out, true)); - } - - public Interpreter(InterpreterCommand command, BufferedReader reader, - PrintWriter writer) - { - this.global = new Global(command, true); - this.interactive = command.interactive.value; - this.emacs = command.emacs.value; - this.reader = reader; - this.writer = writer; - this.matcher = matcher(); + public Interpreter(Global global) { + this.global = global; this.evaluator = new Evaluator(); this.compiler = new Compiler(global, evaluator); // !!! - this.lfiles = new String[0]; - this.ufiles = new String[0]; } //######################################################################## // Public Methods - public void main(String[] program, String main, String[] args) { - if (interactive) showBanner(); - if (program.length > 0) load(lfiles = program); - if (global.reporter.errors() == 0 && main != null) call(main, args); - // !!! can we remove that ? - // Compute something to force loading of Predef & Interpreter - //if (interactive && program.length == 0 && main == null) - //load("module $init$ {}"); - if (interactive) while (handle(read())); - global.stop("total"); - if (!interactive) global.reporter.printSummary(); - } - - public String read() { - writer.print("> "); - writer.flush(); - StringBuffer buffer = new StringBuffer(); - for (boolean stop = false; !stop; ) { - String line; - try { - line = reader.readLine(); - } catch (IOException exception) { - writer.println(); - error(exception.toString()); - System.exit(1); - throw Debug.abort(exception); - } - - if (line == null) { writer.println(); break; } - if (emacs && line.equals("emacs:end")) break; - - if (!emacs) { - line = Strings.trimTrailing(line); - int lastChar = Strings.lastChar(line); - stop = ",;:({=|\\".indexOf(lastChar) < 0; - if (lastChar == '\\') line = line.substring(0,line.length()-1); - } - - buffer.append(line).append('\n'); - - if (!emacs && !stop) { - writer.print("| "); - writer.flush(); - } - } - return buffer.length() == 0 ? null : buffer.toString(); - } - - public boolean handle(String input) { - if (input == null) return exec(QUIT); - String trimed = input.trim(); - return trimed.startsWith(":") ? exec(trimed) : eval(input); - } - - public boolean exec(String input) { - int length = input.indexOf(' '); - length = length < 0 ? input.length() : length; - String command = input.substring(0, length); - PrefixMatcher.Entry[] entries = matcher.lookup(command); - if (entries.length != 1) { - error(matcher.getErrorMessage(command,entries,"command")); - return true; - } - try { - String[] arguments = readArguments(input.substring(length)); - return exec(((Integer)entries[0].value).intValue(), arguments); - } catch (IOException exception) { - error(exception.getMessage()); - return true; - } - } - - public boolean exec(int command) { - return exec(command, new String[0]); - } - - public boolean exec(int command, String[] args) { - switch (command) { - case QUIT: - writer.println("[Leaving " + PRODUCT + "]"); - return false; - - case LOAD: - if (args.length != 0) lfiles = args; - return load(lfiles); - - case USE: - if (args.length != 0) ufiles = args; - return eval(ufiles); - - case GC: - System.gc(); - return true; - - case MEMORY: - Runtime rt = Runtime.getRuntime(); - writer.println("total memory: " + rt.totalMemory()); - writer.println("free memory : " + rt.freeMemory()); - return true; - - case SHOWVER: - writer.println(PRODUCT + " " + VERSION + " -- " + COPYRIGHT); - return true; - - case HELP: - writer.println("interpreter commands:"); - writer.println(Strings.format(matcher.getHelpStrings(" ","\t "))); - return true; - - default: - throw Debug.abort("unknown command " + command); - } - } - - public boolean eval(String input) { - if (input.trim().length() == 0) return true; - global.compile(input + ";", true); - return interpret(true); - } - - public boolean eval(String[] files) { - if (files.length == 0) return true; - global.compile(files, true); - return interpret(true); - } - - public boolean load(String input) { - if (input.trim().length() == 0) return true; - global.compile(input + ";", false); - return interpret(false); + public EvaluatorResult interpret(String input, boolean interactive) { + if (input.trim().length() == 0) return EvaluatorResult.Void; + global.compile(input + ";", interactive); + return interpret(interactive); } - public boolean load(String[] files) { - if (files.length == 0) return true; - global.compile(files, false); - return interpret(false); + public EvaluatorResult interpret(String[] files, boolean interactive) { + if (files.length == 0) return EvaluatorResult.Void; + global.compile(files, interactive); + return interpret(interactive); } - public boolean call(String main, String[] args) { - global.prevPhase(); // !!! - new EntryPointCompiler(PRODUCT, global).compile(main, args); - global.nextPhase(); // !!! - return interpret(false); - } - - public boolean interpret(boolean interactive) { - if (global.reporter.errors() == 0) - show(interpret(new DefaultDefinitionPrinter()), interactive); - Sourcefile.flushSources(); - return true; - } - - public EvaluatorResult interpret(DefinitionPrinter printer) { + public EvaluatorResult interpret(boolean interactive) { try { + if (global.reporter.errors() != 0) return EvaluatorResult.Void; CodeContainer code = compiler.compile(global.units, interactive); - InterpreterSupport.setDefinitionPrinter(printer); evaluator.evaluate(code); EvaluationResult result = InterpreterSupport.getAndResetEvaluationResult(); @@ -279,197 +61,11 @@ public class Interpreter { } } - public void show(EvaluatorResult result, boolean interactive) { - switch (result) { - case Void: - return; - case Value(Object value, String type): - if (interactive) writer.println(value + ": " + type); - return; - case Error(EvaluatorException exception): - writer.println(exception.getScalaErrorMessage(true)); - return; - } - } - - public void showBanner() { - writer.println(" __ __ _ _"); - writer.println(" (_ / /_|| /_| INTERPRETER"); - writer.println("___)\\__/ ||__/ | " + COPYRIGHT); - writer.println(" "); - writer.println(" version: " + VERSION); - writer.println(" type :? to get a list of all interpreter commands"); - writer.println(" "); - } - - //######################################################################## - // Private Methods - argument parsing - - private String[] readArguments(String command) throws IOException { - return readArguments(new PushbackReader(new StringReader(command))); - } - - private String[] readArguments(PushbackReader reader) throws IOException { - List arguments = new ArrayList(); - while (true) { - int c = reader.read(); - if (c == -1) return (String[])arguments.toArray(new String[0]); - if (!Character.isWhitespace((char)c)) { - reader.unread(c); - arguments.add(readArgument(reader)); - } - } - } - - private String readArgument(PushbackReader reader) throws IOException { - StringBuffer value = new StringBuffer(); - StringBuffer token = new StringBuffer(); - while (true) { - int c = read(reader, token); - switch (c) { - case '\"': value.append(readString(reader, token)); break; - case '\\': value.append(readBackslashed(reader, token)); break; - default : - if (!Character.isWhitespace((char)c)) { - value.append((char)c); - break; - } else { - reader.unread(c); - } - case -1 : return value.toString(); - } - token.delete(0, token.length()); - } - } - - private String readBackslashed(PushbackReader reader, StringBuffer input) - throws IOException - { - int c = read(reader, input); - switch (c) { - case ' ' : return " "; - case '\"': return "\""; - case '\\': return "\\"; - default : return input.toString(); - } - } - - private String readString(PushbackReader reader, StringBuffer input) - throws IOException - { - StringBuffer value = new StringBuffer(); - StringBuffer token = new StringBuffer(); - while (true) { - int c = read(reader, token, "unterminated string '" + input + "'"); - switch (c) { - case '\"': input.append((char)c); return value.toString(); - case '\\': value.append(readEscape(reader, token)); break; - default : value.append((char)c); break; - } - input.append(token.toString()); - token.delete(0, token.length()); - } - } - - private char readEscape(PushbackReader reader, StringBuffer input) - throws IOException - { - int c = read(reader, input, - "unterminated escape sequence '" + input + "'"); - switch (c) { - case 'b' : return '\b'; - case 't' : return '\t'; - case 'n' : return '\n'; - case 'f' : return '\f'; - case 'r' : return '\r'; - case '\"': return '\"'; - case '\'': return '\''; - case '\\': return '\\'; - case 'u' : return readUnicode(reader, input); - case '0' : - case '1' : - case '2' : - case '3' : - case '4' : - case '5' : - case '6' : - case '7' : return readOctal(reader, input, c); - default : throw new IOException( - "illegal escape sequence '" + input + "'"); - } - } - - private char readUnicode(PushbackReader reader, StringBuffer input) - throws IOException - { - int value = 0; - boolean illegal = false; - for (int i = 0; i < 4; i++) { - int c = read(reader, input, - "unterminated Unicode escape sequence '" + input + "'"); - switch (c) { - case '0': case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - value = (value << 4) + (c - '0'); break; - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - value = (value << 4) + (c - 'A' + 0x0A); break; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - value = (value << 4) + (c - 'a' + 0x0a); break; - default: - illegal = true; break; - } - } - if (illegal) throw new IOException( - "illegal Unicode escape sequence '" + input + "'"); - return (char)value; - } - - private char readOctal(PushbackReader reader, StringBuffer input,int first) - throws IOException - { - int value = first - '0'; - while (value < 32) { - int c = read(reader, input); - if (c < '0' || '7' < c) { reader.unread(c); break; } - value = (value << 3) + (c - '0'); - } - return (char)value; - } - - private int read(PushbackReader reader, StringBuffer input, String error) - throws IOException - { - int c = read(reader, input); - if (c == -1) throw new IOException(error); - return (char)c; - } - - private int read(PushbackReader reader, StringBuffer input) - throws IOException - { - int c = reader.read(); - if (c != -1) input.append((char)c); - return c; - } - - //######################################################################## - // Private Methods - error messages - - private void error(String message) { - writer.println("Error: " + message); - } - - //######################################################################## - // Private Classes - - private class DefaultDefinitionPrinter implements DefinitionPrinter { - - public void showDefinition(String signature) { - writer.println(signature); - } - - public void showValueDefinition(String signature, Object value) { - writer.println(signature + " = " + value); + public EvaluatorResult toString(Object object, String type) { + try { + return EvaluatorResult.Value(evaluator.toString(object), type); + } catch (EvaluatorException exception) { + return EvaluatorResult.Error(exception); } } diff --git a/sources/scala/tools/scalai/InterpreterShell.java b/sources/scala/tools/scalai/InterpreterShell.java new file mode 100644 index 0000000000..c51174b373 --- /dev/null +++ b/sources/scala/tools/scalai/InterpreterShell.java @@ -0,0 +1,475 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scalai; + +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.PushbackReader; +import java.io.StringReader; +import java.io.PrintWriter; +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; + +import scala.runtime.InterpreterSupport; +import scala.runtime.InterpreterSupport.DefinitionPrinter; + +import scalac.util.Debug; +import scalac.util.Strings; +import scalac.util.PrefixMatcher; + +import scalac.Global; + +public class InterpreterShell { + + //######################################################################## + // Public Constants + + public static final String PRODUCT = Main.PRODUCT; + public static final String VERSION = Main.VERSION; + public static final String COPYRIGHT = "(c) 2002, LAMP/EPFL"; + + //######################################################################## + // Private Constants + + private static final int QUIT = 0; + private static final int LOAD = 1; + private static final int USE = 2; + private static final int GC = 3; + private static final int MEMORY = 4; + private static final int SHOWVER = 5; + private static final int HELP = 6; + + //######################################################################## + // Private Fields + + private final boolean interactive; + private final boolean emacs; + private final BufferedReader reader; + private final PrintWriter writer; + private final PrefixMatcher matcher; + private final Global global; + private final Interpreter interpreter; + + private String[] lfiles; + private String[] ufiles; + + //######################################################################## + // Public Constructors + + public InterpreterShell(InterpreterCommand command) { + this(command, new BufferedReader(new InputStreamReader(System.in)), + new PrintWriter(System.out, true)); + } + + public InterpreterShell(InterpreterCommand command, BufferedReader reader, + PrintWriter writer) + { + this.interactive = command.interactive.value; + this.emacs = command.emacs.value; + this.reader = reader; + this.writer = writer; + this.matcher = matcher(); + this.global = new Global(command, true); + this.interpreter = new Interpreter(global); + this.lfiles = new String[0]; + this.ufiles = new String[0]; + } + + //######################################################################## + // Public Methods - shell + + public void main(String[] program, String main, String[] args) { + if (interactive) showBanner(); + if (program.length > 0) load(lfiles = program); + if (global.reporter.errors() == 0 && main != null) call(main, args); + if (interactive) loop(new DefaultDefinitionPrinter()); + global.stop("total"); // !!! remove ? + if (!interactive) global.reporter.printSummary(); + } + + public void loop(DefinitionPrinter printer) { + InterpreterSupport.setDefinitionPrinter(printer); + while (handle(read())); + InterpreterSupport.setDefinitionPrinter(null); + } + + public boolean handle(String input) { + if (input == null) return exec(QUIT); + String trimed = input.trim(); + if (trimed.startsWith(":")) return exec(trimed); + eval(input); + return true; + } + + public String read() { + writer.print("> "); + writer.flush(); + StringBuffer buffer = new StringBuffer(); + for (boolean stop = false; !stop; ) { + String line; + try { + line = reader.readLine(); + } catch (IOException exception) { + writer.println(); + error(exception.toString()); + System.exit(1); + throw Debug.abort(exception); + } + + if (line == null) { writer.println(); break; } + if (emacs && line.equals("emacs:end")) break; + + if (!emacs) { + line = Strings.trimTrailing(line); + int lastChar = Strings.lastChar(line); + stop = ",;:({=|\\".indexOf(lastChar) < 0; + if (lastChar == '\\') line = line.substring(0,line.length()-1); + } + + buffer.append(line).append('\n'); + + if (!emacs && !stop) { + writer.print("| "); + writer.flush(); + } + } + return buffer.length() == 0 ? null : buffer.toString(); + } + + public void showBanner() { + writer.println(" __ __ _ _"); + writer.println(" (_ / /_|| /_| INTERPRETER"); + writer.println("___)\\__/ ||__/ | " + COPYRIGHT); + writer.println(" "); + writer.println(" version: " + VERSION); + writer.println(" type :? to get a list of all interpreter commands"); + writer.println(" "); + } + + //######################################################################## + // Public Methods - command execution + + public boolean exec(String input) { + int length = input.indexOf(' '); + length = length < 0 ? input.length() : length; + String command = input.substring(0, length); + PrefixMatcher.Entry[] entries = matcher.lookup(command); + if (entries.length != 1) { + error(matcher.getErrorMessage(command, entries, "command")); + return true; + } + try { + String[] arguments = readArguments(input.substring(length)); + return exec(((Integer)entries[0].value).intValue(), arguments); + } catch (IOException exception) { + error(exception.getMessage()); + return true; + } + } + + public boolean exec(int command) { + return exec(command, new String[0]); + } + + public boolean exec(int command, String[] args) { + switch (command) { + case QUIT: + writer.println("[Leaving " + PRODUCT + "]"); + return false; + + case LOAD: + if (args.length != 0) lfiles = args; + load(lfiles); + return true; + + case USE: + if (args.length != 0) ufiles = args; + eval(ufiles); + return true; + + case GC: + System.gc(); + return true; + + case MEMORY: + Runtime rt = Runtime.getRuntime(); + writer.println("total memory: " + rt.totalMemory()); + writer.println("free memory : " + rt.freeMemory()); + return true; + + case SHOWVER: + writer.println(PRODUCT + " " + VERSION + " -- " + COPYRIGHT); + return true; + + case HELP: + writer.println("interpreter commands:"); + writer.println(Strings.format(matcher.getHelpStrings(" ","\t "))); + return true; + + default: + throw Debug.abort("unknown command " + command); + } + } + + //######################################################################## + // Public Methods - interpretation + + public void call(String main, String[] args) { + global.prevPhase(); // !!! + new EntryPointCompiler(PRODUCT, global).compile(main, args); + global.nextPhase(); // !!! + show(interpreter.interpret(false), false); + } + + public void load(String input) { + show(interpreter.interpret(input, false), false); + } + + public void load(String[] files) { + show(interpreter.interpret(files, false), false); + } + + public void eval(String input) { + show(interpreter.interpret(input, true), true); + } + + public void eval(String[] files) { + show(interpreter.interpret(files, true), true); + } + + public void show(EvaluatorResult result, boolean interactive) { + switch (result) { + case Void: + return; + case Value(Object value, String type): + if (interactive) + if (value instanceof String) + writer.println(value + ": " + type); + else + show(interpreter.toString(value, type), interactive); + return; + case Error(EvaluatorException exception): + String name = Thread.currentThread().getName(); + writer.print("Exception in thread \"" + name + "\" "); + writer.println(exception.getScalaErrorMessage(true)); + return; + default: + throw Debug.abort("illegal case", result); + } + } + + //######################################################################## + // Private Methods - matcher initialization + + private PrefixMatcher matcher() { + PrefixMatcher matcher = new PrefixMatcher(); + matcher.insert(":quit", new Integer(QUIT), + "Quit interpreter"); + matcher.insert(":load", new Integer(LOAD), "", + "Load files (or repeat last load if no files are given)"); + matcher.insert(":use", new Integer(USE), "", + "Use files (or repeat last use if no files are given)"); + matcher.insert(":gc", new Integer(GC), + "Run garbage collector"); + matcher.insert(":memory", new Integer(MEMORY), + "Print out memory usage"); + matcher.insert(":help", new Integer(HELP), + "Print out this command summary"); + matcher.insert(":version", new Integer(SHOWVER), + "Print out product version"); + matcher.insert(":?", new Integer(HELP), + "Same as :help"); + return matcher; + } + + //######################################################################## + // Private Methods - error messages + + private void error(String message) { + writer.println("error: " + message); + } + + //######################################################################## + // Private Methods - argument parsing + + private String[] readArguments(String command) throws IOException { + return readArguments(new PushbackReader(new StringReader(command))); + } + + private String[] readArguments(PushbackReader reader) throws IOException { + List arguments = new ArrayList(); + while (true) { + int c = reader.read(); + if (c == -1) return (String[])arguments.toArray(new String[0]); + if (!Character.isWhitespace((char)c)) { + reader.unread(c); + arguments.add(readArgument(reader)); + } + } + } + + private String readArgument(PushbackReader reader) throws IOException { + StringBuffer value = new StringBuffer(); + StringBuffer token = new StringBuffer(); + while (true) { + int c = read(reader, token); + switch (c) { + case '\"': value.append(readString(reader, token)); break; + case '\\': value.append(readBackslashed(reader, token)); break; + default : + if (!Character.isWhitespace((char)c)) { + value.append((char)c); + break; + } else { + reader.unread(c); + } + case -1 : return value.toString(); + } + token.delete(0, token.length()); + } + } + + private String readBackslashed(PushbackReader reader, StringBuffer input) + throws IOException + { + int c = read(reader, input); + switch (c) { + case ' ' : return " "; + case '\"': return "\""; + case '\\': return "\\"; + default : return input.toString(); + } + } + + private String readString(PushbackReader reader, StringBuffer input) + throws IOException + { + StringBuffer value = new StringBuffer(); + StringBuffer token = new StringBuffer(); + while (true) { + int c = read(reader, token, "unterminated string '" + input + "'"); + switch (c) { + case '\"': input.append((char)c); return value.toString(); + case '\\': value.append(readEscape(reader, token)); break; + default : value.append((char)c); break; + } + input.append(token.toString()); + token.delete(0, token.length()); + } + } + + private char readEscape(PushbackReader reader, StringBuffer input) + throws IOException + { + int c = read(reader, input, + "unterminated escape sequence '" + input + "'"); + switch (c) { + case 'b' : return '\b'; + case 't' : return '\t'; + case 'n' : return '\n'; + case 'f' : return '\f'; + case 'r' : return '\r'; + case '\"': return '\"'; + case '\'': return '\''; + case '\\': return '\\'; + case 'u' : return readUnicode(reader, input); + case '0' : + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : return readOctal(reader, input, c); + default : throw new IOException( + "illegal escape sequence '" + input + "'"); + } + } + + private char readUnicode(PushbackReader reader, StringBuffer input) + throws IOException + { + int value = 0; + boolean illegal = false; + for (int i = 0; i < 4; i++) { + int c = read(reader, input, + "unterminated Unicode escape sequence '" + input + "'"); + switch (c) { + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + value = (value << 4) + (c - '0'); break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + value = (value << 4) + (c - 'A' + 0x0A); break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + value = (value << 4) + (c - 'a' + 0x0a); break; + default: + illegal = true; break; + } + } + if (illegal) throw new IOException( + "illegal Unicode escape sequence '" + input + "'"); + return (char)value; + } + + private char readOctal(PushbackReader reader, StringBuffer input,int first) + throws IOException + { + int value = first - '0'; + while (value < 32) { + int c = read(reader, input); + if (c < '0' || '7' < c) { reader.unread(c); break; } + value = (value << 3) + (c - '0'); + } + return (char)value; + } + + private int read(PushbackReader reader, StringBuffer input, String error) + throws IOException + { + int c = read(reader, input); + if (c == -1) throw new IOException(error); + return (char)c; + } + + private int read(PushbackReader reader, StringBuffer input) + throws IOException + { + int c = reader.read(); + if (c != -1) input.append((char)c); + return c; + } + + //######################################################################## + // Private Classes + + private class DefaultDefinitionPrinter implements DefinitionPrinter { + + public void showDefinition(String signature) { + writer.println(signature); + } + + public void showValueDefinition(String signature, Object value) { + EvaluatorResult result = interpreter.toString(value, null); + switch (result) { + case Value(Object string, _): + writer.println(signature + " = " + string); + return; + case Error(EvaluatorException exception): + writer.print(signature + " = "); + writer.println(exception.getScalaErrorMessage(true)); + return; + default: + throw Debug.abort("illegal case", result); + } + } + } + + //######################################################################## +} diff --git a/sources/scala/tools/scalai/Main.java b/sources/scala/tools/scalai/Main.java index 87532646df..9fcfbc5f30 100644 --- a/sources/scala/tools/scalai/Main.java +++ b/sources/scala/tools/scalai/Main.java @@ -30,8 +30,8 @@ public class Main { InterpreterCommand command = new InterpreterCommand( PRODUCT, VERSION, reporter, new PhaseRepository()); if (command.parse(args)) { - Interpreter interpreter = new Interpreter(command); - interpreter.main(command.files.toArray(), + InterpreterShell shell = new InterpreterShell(command); + shell.main(command.files.toArray(), command.program.main, command.program.args); } System.exit((reporter.errors() > 0) ? 1 : 0); -- cgit v1.2.3