summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2003-03-04 17:18:51 +0000
committerpaltherr <paltherr@epfl.ch>2003-03-04 17:18:51 +0000
commit59ed04e4f2c3b10b41928840c405f0d71cdac68e (patch)
tree656fe75173c839d4725b6f4a9b1ee7b8866e78e3 /sources
parent6bd6a0b409b8f7d6c6c84dbb457e7a97b11ee158 (diff)
downloadscala-59ed04e4f2c3b10b41928840c405f0d71cdac68e.tar.gz
scala-59ed04e4f2c3b10b41928840c405f0d71cdac68e.tar.bz2
scala-59ed04e4f2c3b10b41928840c405f0d71cdac68e.zip
- Added scala interpreter
Diffstat (limited to 'sources')
-rw-r--r--sources/scala/tools/scalai/Code.java120
-rw-r--r--sources/scala/tools/scalai/CodeBuffer.java73
-rw-r--r--sources/scala/tools/scalai/CodeContainer.java33
-rw-r--r--sources/scala/tools/scalai/CodeGenerator.java20
-rw-r--r--sources/scala/tools/scalai/CodePromise.java45
-rw-r--r--sources/scala/tools/scalai/Compiler.java508
-rw-r--r--sources/scala/tools/scalai/Constants.java97
-rw-r--r--sources/scala/tools/scalai/EntryPointCompiler.java123
-rw-r--r--sources/scala/tools/scalai/Environment.java205
-rw-r--r--sources/scala/tools/scalai/Evaluator.java538
-rw-r--r--sources/scala/tools/scalai/EvaluatorException.java86
-rw-r--r--sources/scala/tools/scalai/EvaluatorResult.java21
-rw-r--r--sources/scala/tools/scalai/ExpressionCompiler.java288
-rw-r--r--sources/scala/tools/scalai/ExpressionContext.java114
-rw-r--r--sources/scala/tools/scalai/Function.java90
-rw-r--r--sources/scala/tools/scalai/Interpreter.java444
-rw-r--r--sources/scala/tools/scalai/InterpreterCommand.java62
-rw-r--r--sources/scala/tools/scalai/JavaMirror.java245
-rw-r--r--sources/scala/tools/scalai/Main.java41
-rw-r--r--sources/scala/tools/scalai/Override.java60
-rw-r--r--sources/scala/tools/scalai/PathClassLoader.java46
-rw-r--r--sources/scala/tools/scalai/ScalaFunction.java53
-rw-r--r--sources/scala/tools/scalai/ScalaObject.java60
-rw-r--r--sources/scala/tools/scalai/ScalaTemplate.java99
-rw-r--r--sources/scala/tools/scalai/SymbolWriter.java42
-rw-r--r--sources/scala/tools/scalai/Template.java40
-rw-r--r--sources/scala/tools/scalai/Variable.java59
27 files changed, 3612 insertions, 0 deletions
diff --git a/sources/scala/tools/scalai/Code.java b/sources/scala/tools/scalai/Code.java
new file mode 100644
index 0000000000..ac917211f9
--- /dev/null
+++ b/sources/scala/tools/scalai/Code.java
@@ -0,0 +1,120 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Code.java,v 1.13 2002/09/06 13:04:01 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import scalac.symtab.Symbol;
+import scalac.util.Debug;
+
+public class Code {
+
+ //########################################################################
+ // Public Cases
+
+ public case Block(Code[] stats, Code value);
+
+ public case Label(Symbol symbol, Variable[] variables, Code expression);
+
+ public case Create(ScalaTemplate template); // !!! remove ?
+ public case Invoke(Code target, Function function, Code[] parameters, int pos, Symbol method);
+ public case Load(Code target, Variable variable);
+ public case Store(Code target, Variable variable, Code expression);
+
+ public case Box(Code value);
+
+ public case If(Code cond, Code thenp, Code elsep);
+ public case Or(Code lf, Code rg);
+ public case And(Code lf, Code rg);
+
+ public case IsScala(Code target, Symbol symbol);
+ public case IsJava(Code target, Class clasz);
+
+ public case Literal(Object value);
+ public case Self;
+ public case Null;
+
+ //########################################################################
+ // Public Methods
+
+ public String toString() {
+ switch (this) {
+
+ case Block(Code[] stats, Code value):
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Block([").append('\n');
+ for (int i = 0; i < stats.length; i++) {
+ if (i > 0) buffer.append(",\n");
+ buffer.append(stats[i]);
+ }
+ buffer.append("], ").append(value).append(")");
+ return buffer.toString();
+
+ case Label(Symbol symbol, Variable[] variables, Code expression):
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Label(").append(symbol).append(",[");
+ for (int i = 0; i < variables.length; i++) {
+ if (i > 0) buffer.append(",\n");
+ buffer.append(variables[i]);
+ }
+ buffer.append("],").append(expression).append(")");
+ return buffer.toString();
+
+ case Create(ScalaTemplate template):
+ return "Create(" + template + ")";
+
+ case Invoke(Code target, Function function, Code[] parameters, int pos, Symbol method):
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Invoke(" + target + "," + function + "," + "[\n");
+ for (int i = 0; i < parameters.length; i++) {
+ if (i > 0) buffer.append(",\n");
+ buffer.append(parameters[i]);
+ }
+ buffer.append("])");
+ return buffer.toString();
+
+ case Load(Code target, Variable variable):
+ return "Load(" + target + "," + variable + ")";
+
+ case Store(Code target, Variable variable, Code expression):
+ return "Store(" + target + "," + variable + "," + expression + ")";
+
+ case Box(Code value):
+ return "Box(" + value + ")";
+
+ case If(Code cond, Code thenp, Code elsep):
+ return "If(" + cond + "," + thenp + "," + elsep + ")";
+
+ case Or(Code lf, Code rg):
+ return "Or(" + lf + "," + rg + ")";
+
+ case And(Code lf, Code rg):
+ return "And(" + lf + "," + rg + ")";
+
+ case IsScala(Code target, Symbol symbol):
+ return "IsScala(" + target + "," + symbol + ")";
+
+ case IsJava(Code target, Class clasz):
+ return "IsJava(" + target + "," + clasz + ")";
+
+ case Literal(Object value):
+ return "Literal(" + value + ")";
+
+ case Self:
+ return "Self";
+
+ case Null:
+ return "Null";
+
+ default:
+ throw Debug.abort("illegal code", this);
+ }
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/CodeBuffer.java b/sources/scala/tools/scalai/CodeBuffer.java
new file mode 100644
index 0000000000..ae11304321
--- /dev/null
+++ b/sources/scala/tools/scalai/CodeBuffer.java
@@ -0,0 +1,73 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: CodeBuffer.java,v 1.3 2002/06/13 15:24:14 paltherr Exp $
+// $Id$
+
+package scalai;
+
+public class CodeBuffer {
+
+ //########################################################################
+ // Private Fields
+
+ private Code[] buffer;
+ private int size;
+
+ //########################################################################
+ // Public Constructors
+
+ public CodeBuffer() {
+ this.buffer = null;
+ this.size = 0;
+ }
+
+ //########################################################################
+ // Public Methods
+
+ public CodeBuffer append(Code code) {
+ switch (code) {
+
+ case Block(Code[] stats, Code value):
+ insure(stats.length + 1);
+ for (int i = 0; i < stats.length; i++) buffer[size++] = stats[i];
+ buffer[size++] = value;
+ return this;
+
+ default:
+ insure(1);
+ buffer[size++] = code;
+ return this;
+ }
+ }
+
+ public Code code(Code value) {
+ if (size == 0) return value;
+ Code[] stats = buffer;
+ if (size != stats.length) {
+ Code[] array = new Code[size];
+ System.arraycopy(stats, 0, array, 0, size);
+ stats = array;
+ }
+ return Code.Block(stats, value);
+ }
+
+ //########################################################################
+ // Private Methods
+
+ private void insure(int count) {
+ if (buffer == null) {
+ buffer = new Code[count];
+ } else {
+ if (size + count < buffer.length) return;
+ Code[] array = new Code[size + Math.max(count, size)];
+ System.arraycopy(buffer, 0, array, 0, size);
+ buffer = array;
+ }
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/CodeContainer.java b/sources/scala/tools/scalai/CodeContainer.java
new file mode 100644
index 0000000000..e1f717cf6f
--- /dev/null
+++ b/sources/scala/tools/scalai/CodeContainer.java
@@ -0,0 +1,33 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: CodeContainer.java,v 1.1 2002/06/06 11:42:25 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import scalac.symtab.Symbol;
+
+public class CodeContainer {
+
+ //########################################################################
+ // Public Constructors
+
+ public CodeContainer(Symbol symbol, Code code, int stacksize) {
+ this.symbol = symbol;
+ this.code = code;
+ this.stacksize = stacksize;
+ }
+
+ //########################################################################
+ // Public Fields
+
+ public final Symbol symbol;
+ public final Code code;
+ public final int stacksize;
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/CodeGenerator.java b/sources/scala/tools/scalai/CodeGenerator.java
new file mode 100644
index 0000000000..75e17aac3f
--- /dev/null
+++ b/sources/scala/tools/scalai/CodeGenerator.java
@@ -0,0 +1,20 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: CodeGenerator.java,v 1.1 2002/06/06 11:42:25 paltherr Exp $
+// $Id$
+
+package scalai;
+
+public abstract class CodeGenerator {
+
+ //########################################################################
+ // Public Methods
+
+ public abstract CodeContainer generate();
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/CodePromise.java b/sources/scala/tools/scalai/CodePromise.java
new file mode 100644
index 0000000000..33e95c0b15
--- /dev/null
+++ b/sources/scala/tools/scalai/CodePromise.java
@@ -0,0 +1,45 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: CodePromise.java,v 1.1 2002/06/06 11:42:25 paltherr Exp $
+// $Id$
+
+package scalai;
+
+public final class CodePromise {
+
+ //########################################################################
+ // Private Fields
+
+ private CodeGenerator generator;
+ private CodeContainer container;
+
+ //########################################################################
+ // Public Constructors
+
+ public CodePromise(CodeGenerator generator) {
+ this.generator = generator;
+ this.container = null;
+ }
+
+ public CodePromise(CodeContainer container) {
+ this.generator = null;
+ this.container = container;
+ }
+
+ //########################################################################
+ // Public Methods
+
+ public CodeContainer force() {
+ if (container == null) {
+ container = generator.generate();
+ generator = null;
+ }
+ return container;
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/Compiler.java b/sources/scala/tools/scalai/Compiler.java
new file mode 100644
index 0000000000..ad2386225a
--- /dev/null
+++ b/sources/scala/tools/scalai/Compiler.java
@@ -0,0 +1,508 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Compiler.java,v 1.19 2002/10/01 16:14:07 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.lang.reflect.Proxy;
+import java.lang.reflect.InvocationHandler;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import scalac.Unit;
+import scalac.Global;
+import scalac.ast.Tree;
+import scalac.ast.Tree.ValDef;
+import scalac.ast.TreeGen;
+import scalac.symtab.Definitions;
+import scalac.symtab.Type;
+import scalac.symtab.Symbol;
+import scalac.symtab.TermSymbol;
+import scalac.util.Debug;
+import scalac.util.Name;
+import scalac.util.Position;
+
+public class Compiler {
+
+ //########################################################################
+
+ private final Symbol WRITER;
+ private final Symbol WRITER_WRITE;
+ private final Type SYMBOL_TYPE;
+
+ //########################################################################
+
+ private final Global global;
+ private final Definitions definitions;
+ private final TreeGen make;
+ private final Constants constants;
+ private final ClassLoader loader;
+ private final Environment environment;
+ private final Evaluator evaluator; // !!! remove
+ private final SymbolWriter writer;
+ private final Map any_methods;
+
+ private boolean interactive;
+
+ public Compiler(Global global, Evaluator evaluator, SymbolWriter writer) {
+ this.global = global;
+ this.definitions = global.definitions;
+ this.make = global.treeGen;
+ this.constants = new Constants();
+ this.loader = new PathClassLoader(global.classPath);
+ scala.runtime.RunTime.setClassLoader(loader);
+ JavaMirror mirror = new JavaMirror(definitions, loader);
+ this.environment = new Environment(this, mirror);
+ this.evaluator = evaluator;
+ this.writer = writer;
+ this.any_methods = new HashMap();
+
+ Name WRITER_N = Name.fromString(SymbolWriter.class.getName());
+ Type WRITER_TYPE = definitions.getType(WRITER_N);
+ this.WRITER = newGlobalVariable(WRITER_TYPE, writer);
+ this.WRITER_WRITE = WRITER_TYPE.lookup(Name.fromString("write2"));
+
+ Name SYMBOL_N = Name.fromString(Symbol.class.getName());
+ this.SYMBOL_TYPE = definitions.getType(SYMBOL_N);
+
+ environment.insertFunction(definitions.STRING_PLUS_ANY, Function.StringPlus); // !!!
+ // !!! ANY_PLUS_STRING is commented out in definitions
+ // !!! environment.insertFunction(definitions.ANY_PLUS_STRING, Function.StringPlus); // !!!
+ environment.insertFunction(definitions.THROW, Function.Throw);
+ // !!! environment.insertFunction(definitions.MATCH, ...);
+ // !!! environment.insertFunction(definitions.IS, ...);
+ // !!! environment.insertFunction(definitions.AS, ...);
+
+ java.lang.reflect.Method getInvocationHandler_method = null;
+ try {
+ getInvocationHandler_method = Proxy.class.getMethod(
+ "getInvocationHandler",
+ new Class[] {Object.class});
+ } catch (Exception exception) {
+ throw Debug.abort("getInvocationHandler", exception);
+ }
+
+ // !!! method java.lang.Object.clone()
+
+ java.lang.reflect.Method equals_method = null;
+ try {
+ equals_method = Object.class.getMethod("equals",
+ new Class[] {Object.class});
+ } catch (Exception exception) {
+ throw Debug.abort("equals", exception);
+ }
+ CodePromise equals_code = new CodePromise(
+ new CodeContainer(
+ null, // !!!
+ Code.Invoke(
+ Code.Invoke(
+ Code.Null,
+ Function.JavaMethod(getInvocationHandler_method),
+ new Code[] {
+ Code.Self},
+ Position.NOPOS, null // !!!
+ ),
+ Function.JavaMethod(equals_method),
+ new Code[] {
+ Code.Load(
+ Code.Null, Variable.Context(Evaluator.Levels.ARGS, 0))},
+ Position.NOPOS, null), // !!!
+ 0));
+ // !!! any_methods.put(_, equals_code);
+ any_methods.put(equals_method, equals_code);
+
+ // !!! method java.lang.Object.equals(Object)
+ // !!! method java.lang.Object.finalize()
+ // !!! method java.lang.Object.getClass()
+
+ java.lang.reflect.Method hashCode_method = null;
+ try {
+ hashCode_method = Object.class.getMethod("hashCode", new Class[0]);
+ } catch (Exception exception) {
+ throw Debug.abort("hashCode", exception);
+ }
+ CodePromise hashCode_code = new CodePromise(
+ new CodeContainer(
+ definitions.HASHCODE,
+ Code.Invoke(
+ Code.Self, Function.HashCode, new Code[0],
+ Position.NOPOS, definitions.HASHCODE),
+ 0));
+ any_methods.put(definitions.HASHCODE, hashCode_code);
+ any_methods.put(hashCode_method, hashCode_code);
+ environment.insertFunction(definitions.HASHCODE,
+ Function.JavaMethod(hashCode_method));
+ Override hashCode_override = Override.empty();
+ hashCode_override.insert(hashCode_method).insert(definitions.HASHCODE);
+ environment.insertOverride(definitions.HASHCODE, hashCode_override);
+
+ // !!! method java.lang.Object.notify()
+ // !!! method java.lang.Object.notifyAll()
+
+ java.lang.reflect.Method toString_method = null;
+ try {
+ toString_method = Object.class.getMethod("toString", new Class[0]);
+ } catch (Exception exception) {
+ throw Debug.abort("toString", exception);
+ }
+ CodePromise toString_code = new CodePromise(
+ new CodeContainer(
+ definitions.TOSTRING,
+ Code.Invoke(
+ Code.Self, Function.ToString, new Code[0],
+ Position.NOPOS, definitions.TOSTRING),
+ 0));
+ any_methods.put(definitions.TOSTRING, toString_code);
+ any_methods.put(toString_method, toString_code);
+ environment.insertFunction(definitions.TOSTRING,
+ Function.JavaMethod(toString_method));
+ Override toString_override = Override.empty();
+ toString_override.insert(toString_method).insert(definitions.TOSTRING);
+ environment.insertOverride(definitions.TOSTRING, toString_override);
+
+ // !!! method java.lang.Object.wait()
+ // !!! method java.lang.Object.wait(long)
+ // !!! method java.lang.Object.wait(long, int)
+
+ java.lang.reflect.Method bang_method = null;
+ try {
+ bang_method = scala.Boolean.class.getMethod("$bang",
+ new Class[0]);
+ } catch (Exception exception) {
+ throw Debug.abort("$bang", exception);
+ }
+
+ CodePromise eqeq_code = new CodePromise(
+ new CodeContainer(
+ definitions.EQEQ,
+ Code.Invoke(
+ Code.Self, Function.JavaMethod(equals_method), new Code[] {
+ Code.Load(
+ Code.Null,
+ Variable.Context(Evaluator.Levels.ARGS, 0)) },
+ Position.NOPOS, definitions.EQEQ),
+ 0));
+ any_methods.put(definitions.EQEQ, eqeq_code);
+ environment.insertFunction(definitions.EQEQ, Function.EqEq);
+ Override eqeq_override = Override.empty().insert(definitions.EQEQ);
+ environment.insertOverride(definitions.EQEQ, eqeq_override);
+
+ CodePromise bangeq_code = new CodePromise(
+ new CodeContainer(
+ definitions.BANGEQ,
+ Code.Invoke(
+ Code.Box(
+ Code.Invoke(
+ Code.Self, Function.EqEq, new Code[] {
+ Code.Load(
+ Code.Null,
+ Variable.Context(Evaluator.Levels.ARGS, 0)) },
+ Position.NOPOS, definitions.BANGEQ)),
+ Function.JavaMethod(bang_method),
+ new Code[0],
+ Position.NOPOS, definitions.BANGEQ),
+ 0));
+ any_methods.put(definitions.BANGEQ, bangeq_code);
+ environment.insertFunction(definitions.BANGEQ, Function.BangEq);
+ Override bangeq_override = Override.empty().insert(definitions.BANGEQ);
+ environment.insertOverride(definitions.BANGEQ, bangeq_override);
+ }
+
+ //########################################################################
+
+ public ScalaTemplate load(Symbol symbol, Tree.ClassDef tree) {
+ assert tree.tparams .length == 0 : Debug.show(tree);
+ assert tree.vparams .length == 1 : Debug.show(tree);
+ assert tree.vparams[0].length == 0 : Debug.show(tree);
+ return compileTemplate(symbol, tree.impl.body);
+ }
+
+ public ScalaTemplate compileTemplate(Symbol symbol, Tree[] body) {
+ Set supertypes = new HashSet();
+ List interfaces = new ArrayList();
+ getTypes(supertypes, interfaces, symbol);
+ Class[] proxytype = new Class[interfaces.size()];
+ interfaces.toArray(proxytype);
+ Class proxy = Proxy.getProxyClass(loader, proxytype);
+ Function constructor = getConstructor(proxy);
+ Type[] bases = symbol.parents();
+ Map methods;
+ List fields;
+ if (symbol.isInterface() || bases.length == 0) {
+ methods = new HashMap(any_methods);
+ fields = new ArrayList();
+ } else {
+ Template template = environment.lookupTemplate(bases[0].symbol());
+ switch (template) {
+
+ case Global(ScalaTemplate template_): // !!!
+ methods = template_.getMethods();
+ fields = template_.getFields();
+ break;
+
+ case JavaClass(_):
+ methods = new HashMap(any_methods);
+ fields = new ArrayList();
+ break;
+
+ default:
+ throw Debug.abort("illegal case", template);
+ }
+ }
+ for (int i = 0; i < body.length; i++) {
+ addTemplateMember(methods, fields, body[i]);
+ }
+ return new ScalaTemplate(evaluator, symbol, constructor, methods, fields.toArray());
+ }
+
+ //########################################################################
+
+ public CodePromise compile(Symbol symbol, Tree.DefDef tree) {
+ assert tree.tparams.length == 0 : Debug.show(tree);
+ assert tree.vparams.length == 1 : Debug.show(tree);
+ return new CodePromise(new ScalaFunction(this, symbol, tree.vparams[0],tree.rhs));
+ }
+
+ //########################################################################
+ //
+
+ public CodeContainer compile(Symbol owner, Tree tree) {
+ return compile(owner, tree, new Symbol[0]); // !!!
+ }
+
+ public CodeContainer compile(Symbol owner, Tree tree, ValDef[] params) {
+ return compile(owner, tree, Tree.symbolOf(params));
+ }
+
+ public CodeContainer compile(Symbol owner, Tree tree, Symbol[] params) {
+ ExpressionContext context = new ExpressionContext(environment, owner);
+ ExpressionCompiler worker = new ExpressionCompiler(definitions, constants, context, params);
+ return worker.compile(tree);
+ }
+
+ public CodeContainer compile(Symbol owner, ArrayList items) {
+ return compile(owner, items, new Symbol[0]); // !!!
+ }
+
+ public CodeContainer compile(Symbol owner, ArrayList items,Symbol[]params){
+ ExpressionContext context = new ExpressionContext(environment, owner);
+ ExpressionCompiler worker = new ExpressionCompiler(definitions, constants, context, params);
+ return worker.compile(items);
+ }
+
+ //########################################################################
+ // Private Methods -
+
+ public CodeContainer compile(Unit[] units, boolean interactive) {
+ this.interactive = interactive;
+ ArrayList buffer = new ArrayList();
+ for (int i = 0; i < units.length; i++) declare(buffer, units[i].body);
+ return compile(null, buffer);
+ }
+
+ //########################################################################
+ // Private Methods -
+
+ private void declare(ArrayList buffer, Tree[] trees) {
+ for (int i = 0; i < trees.length; i++) declare(buffer, trees[i]);
+ }
+
+ private void declare(ArrayList buffer, Tree tree) {
+ Symbol symbol = tree.symbol();
+ switch (tree) {
+
+ case Empty:
+ return;
+
+ case ClassDef(_, _, _, _, _, _):
+ environment.insertClassDef(symbol, (Tree.ClassDef)tree);
+ return;
+
+ // !!! these could be removed
+ case PackageDef(Tree packaged, Tree.Template(Tree[] bases, Tree[] body)):
+ assert packaged.symbol().isPackage() : Debug.show(tree); // !!! was isJavaPackage
+ assert bases.length == 0 : Debug.show(tree);
+ declare(buffer, body);
+ return;
+
+ case ValDef(_, _, _, Tree body):
+ if (symbol.isModule()) {
+ environment.insertVariable(symbol, Variable.Module(new CodePromise(new ModuleBuilder(this, symbol, body)), null));
+ if (mustShowDefinition(symbol)) writer.write1(symbol);
+ } else {
+ Variable variable = environment.insertVariable(symbol, Variable.Global(constants.zero(symbol.type())));
+ if (body != Tree.Empty) buffer.add(make.Assign(make.Ident(symbol), body));
+ if (mustShowDefinition(symbol)) buffer.add(
+ make.Apply(make.Select(make.Ident(WRITER), WRITER_WRITE),
+ new Tree[] {
+ make.Ident(newGlobalVariable(SYMBOL_TYPE, symbol)),
+ make.Ident(symbol)}));
+ }
+ return;
+
+ case DefDef(_, _, _, _, _, _):
+ CodePromise function = compile(symbol, (Tree.DefDef)tree);
+ environment.insertFunction(symbol, Function.Global(function));
+ if (isEntryPoint(symbol)) {
+ buffer.add(make.Apply(make.Ident(symbol), new Tree[0]));
+ } else if (mustShowDefinition(symbol)) {
+ writer.write1(symbol);
+ }
+ return;
+
+ default:
+ buffer.add(tree);
+ return;
+ }
+ }
+
+ //########################################################################
+ // Private Methods -
+
+ // !!! move elsewhere ?
+ public static final Name MAIN_N = Name.fromString("main");
+
+ private boolean isEntryPoint(Symbol symbol) {
+ if (symbol.name != MAIN_N) return false;
+ switch (symbol.type()) {
+ case MethodType(Symbol[] vparams, _): return vparams.length == 0;
+ default: return true;
+ }
+ }
+
+ private boolean mustShowDefinition(Symbol symbol) {
+ // !!! the last test is to avoid printing of lifted symbols
+ return
+ (interactive &&
+ // !!! symbol.owner() == definitions.CONSOLE_CLASS &&
+ writer != null && symbol.name.lastPos((byte)'$') < 0); // !!! '$'
+ }
+
+ private Symbol newGlobalVariable(Type type, Object value) {
+ Symbol symbol = new TermSymbol(Position.NOPOS,
+ Name.fromString(value.toString()), definitions.ROOT, 0);
+ symbol.setInfo(type);
+ environment.insertVariable(symbol, Variable.Global(value));
+ return symbol;
+ }
+
+ //########################################################################
+ // Private Methods - template types
+
+ private void getTypes(Set supertypes, List interfaces, Symbol type) {
+ if (supertypes.contains(type)) return; else supertypes.add(type);
+ if (!type.isJava()) {
+ Type[] basetypes = type.parents();
+ for (int i = 0; i < basetypes.length; i++) {
+ getTypes(supertypes, interfaces, basetypes[i].symbol());
+ }
+ return;
+ } else {
+ Template template = environment.lookupTemplate(type);
+ switch (template) {
+ case JavaClass(Class clasz):
+ getTypes(supertypes, interfaces, clasz);
+ return;
+ default:
+ Debug.abort("illegal template", template);
+ }
+ }
+ }
+
+ private void getTypes(Set supertypes, List interfaces, Class type) {
+ if (supertypes.contains(type)) return; else supertypes.add(type);
+ if (type.isInterface()) {
+ interfaces.add(type);
+ } else {
+ Class supertype = type.getSuperclass();
+ if (supertype != null) getTypes(supertypes, interfaces, supertype);
+ Class[] basetypes = type.getInterfaces();
+ for (int i = 0; i < basetypes.length; i++) {
+ getTypes(supertypes, interfaces, basetypes[i]);
+ }
+ }
+ }
+
+ //########################################################################
+ // Private Methods - template constructors
+
+ private static final Class[] CSTR_PARAMS =
+ new Class[] { InvocationHandler.class }; // !!! remove ?
+
+ private Function getConstructor(Class proxy) {
+ try {
+ return Function.JavaConstructor(proxy.getConstructor(CSTR_PARAMS));
+ } catch (NoSuchMethodException exception) {
+ throw Debug.abort(exception);
+ }
+ }
+
+ //########################################################################
+ // Private Methods - template members
+
+ private void addTemplateMember(Map methods, List fields, Tree tree) {
+ Symbol symbol = tree.symbol();
+ switch (tree) {
+
+ case Empty:
+ return;
+
+ case ClassDef(_, _, _, _, _, _):
+ environment.insertClassDef(symbol, (Tree.ClassDef)tree);
+ return;
+
+ case ValDef(_, _, _, Tree body):
+ assert body == Tree.Empty : Debug.show(tree);
+ assert !symbol.isModule() : Debug.show(tree);
+ int index = fields.size();
+ fields.add(constants.zero(symbol.type()));
+ environment.insertVariable(symbol, Variable.Member(index));
+ return;
+
+ case DefDef(_, _, _, _, _, _):
+ assert !methods.containsKey(symbol) : Debug.show(symbol);
+ CodePromise function = compile(symbol, (Tree.DefDef)tree);
+ Override override = environment.lookupOverride(symbol);
+ for (Iterator i = override.iterator(); i.hasNext(); ) {
+ methods.put(i.next(), function);
+ }
+ environment.insertFunction(symbol, Function.Member(symbol));
+ return;
+
+ default:
+ throw Debug.abort("illegal tree", tree);
+ }
+ }
+
+ //########################################################################
+ // !!!
+
+ public static class ModuleBuilder extends CodeGenerator {
+
+ private final Compiler compiler;
+ private final Symbol symbol;
+ private final Tree body;
+
+ public ModuleBuilder(Compiler compiler, Symbol symbol, Tree body) {
+ this.compiler = compiler;
+ this.symbol = symbol;
+ this.body = body;
+ }
+
+ public CodeContainer generate() {
+ return compiler.compile(symbol, body);
+ }
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/Constants.java b/sources/scala/tools/scalai/Constants.java
new file mode 100644
index 0000000000..3b87408b96
--- /dev/null
+++ b/sources/scala/tools/scalai/Constants.java
@@ -0,0 +1,97 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Constants.java,v 1.3 2002/07/09 08:35:02 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import scala.runtime.RunTime;
+
+import scalac.symtab.Type;
+import scalac.symtab.TypeTags;
+import scalac.util.Debug;
+
+public class Constants {
+
+ //########################################################################
+ // Public Constants - kinds
+
+ // !!! use literal constants ?
+ public static final int UNIT = TypeTags.UNIT;
+ public static final int BOOLEAN = TypeTags.BOOLEAN;
+ public static final int BYTE = TypeTags.BYTE;
+ public static final int SHORT = TypeTags.SHORT;
+ public static final int INT = TypeTags.INT;
+ public static final int LONG = TypeTags.LONG;
+ public static final int FLOAT = TypeTags.FLOAT;
+ public static final int DOUBLE = TypeTags.DOUBLE;
+ public static final int CHAR = TypeTags.CHAR;
+ public static final int STRING = TypeTags.STRING;
+ public static final int OBJECT = TypeTags.STRING + 1;
+
+ //########################################################################
+ // Public Methods - literal
+
+ // !!! remove ?
+ public Object literal( ) { return RunTime.box ( ); }
+ public Object literal(boolean value) { return new Boolean (value); }
+ public Object literal(byte value) { return new Byte (value); }
+ public Object literal(short value) { return new Short (value); }
+ public Object literal(char value) { return new Character(value); }
+ public Object literal(int value) { return new Integer (value); }
+ public Object literal(long value) { return new Long (value); }
+ public Object literal(float value) { return new Float (value); }
+ public Object literal(double value) { return new Double (value); }
+ public Object literal(Object value) { return value ; }
+
+ // !!! remove ?
+ public Object literal(int kind, Object value) {
+ switch (kind) {
+ case UNIT : return literal();
+ case BOOLEAN: return literal(((Boolean)value).booleanValue());
+ case BYTE : return literal(((Number)value).byteValue());
+ case SHORT : return literal(((Number)value).shortValue());
+ case INT : return literal(((Number)value).intValue());
+ case LONG : return literal(((Number)value).longValue());
+ case FLOAT : return literal(((Number)value).floatValue());
+ case DOUBLE : return literal(((Number)value).doubleValue());
+ case CHAR : return literal((char)((Number)value).intValue());
+ case STRING : return literal(value);
+ case OBJECT : return literal(value);
+ default : throw Debug.abort("illegal kind " + kind);
+ }
+ }
+
+ //########################################################################
+ // Public Methods - zero
+
+ public Object zero(Type type) {
+ switch (type) {
+ case TypeRef(_, _, _) : return literal(null);
+ case UnboxedArrayType(_) : return literal(null);
+ case UnboxedType(int kind): return zero(kind);
+ default: throw Debug.abort("illegal type", type);
+ }
+ }
+
+ public Object zero(int kind) {
+ switch (kind) {
+ case UNIT : return literal();
+ case BOOLEAN: return literal(false);
+ case BYTE : return literal((byte)0);
+ case SHORT : return literal((short)0);
+ case CHAR : return literal((char)0);
+ case INT : return literal((int)0);
+ case LONG : return literal((long)0);
+ case FLOAT : return literal((float)0);
+ case DOUBLE : return literal((double)0);
+ default : throw Debug.abort("illegal kind " + kind);
+ }
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/EntryPointCompiler.java b/sources/scala/tools/scalai/EntryPointCompiler.java
new file mode 100644
index 0000000000..f32f40cbfb
--- /dev/null
+++ b/sources/scala/tools/scalai/EntryPointCompiler.java
@@ -0,0 +1,123 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: EntryPointCompiler.java,v 1.1 2002/08/30 14:28:25 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import scalac.Global;
+import scalac.Unit;
+import scalac.ast.Tree;
+import scalac.ast.parser.Sourcefile;
+import scalac.symtab.Type;
+import scalac.symtab.Symbol;
+import scalac.util.Name;
+import scalac.util.Position;
+
+import scalac.symtab.TermSymbol;
+
+public class EntryPointCompiler {
+
+ //########################################################################
+ // Private Fields
+
+ private final String product;
+ private final Global global;
+ private final Type MAIN_TYPE; // !!! move elsewhere
+
+ //########################################################################
+ // Public Constructors
+
+ public EntryPointCompiler(String product, Global global) {
+ this.product = product;
+ this.global = global;
+ Name ARGS_N = Name.fromString("args");
+ Symbol args = new TermSymbol(0, ARGS_N, null, 0);
+ args.setInfo(global.definitions.arrayType(global.definitions.STRING_TYPE));
+ this.MAIN_TYPE = Type.MethodType(new Symbol[] {args}, global.definitions.UNIT_TYPE);
+ }
+
+ //########################################################################
+ // Public Methods
+
+ public void compile(String main, String[] args) {
+ String names = main.replace('/', '.') + (main.length() > 0 ? "." : "");
+ if (names.length() > 0 && names.charAt(0) == '.') {
+ error("illegal module name '" + main + "'");
+ return;
+ }
+
+ Symbol module = global.definitions.ROOT;
+ for (int i = 0, j; (j = names.indexOf('.', i)) >= 0; i = j + 1) {
+ Name name = Name.fromString(names.substring(i, j));
+ if (module == Symbol.NONE) {
+ error("could not find module '" + main.substring(0, j) + "'");
+ return;
+ }
+ if (module == Symbol.ERROR) {
+ error("term '" + main.substring(0, j) + "' is not a module");
+ return;
+ }
+ }
+
+ Name name = Compiler.MAIN_N;
+ Type type = MAIN_TYPE;
+ Symbol method = getMethod(module, name, type.erasure());
+ if (method == Symbol.NONE) {
+ error("module '" + main + "' has no method '" + name + "'");
+ return;
+ }
+ if (method == Symbol.ERROR) {
+ error("module '" + main + "' has no method '" + name +
+ "' with type '" + type + "'");
+ return;
+ }
+
+ int pos = Position.NOPOS;
+ global.units = new Unit[1];
+ global.units[0] = new Unit(global, new Sourcefile((byte[])null,false));
+ global.units[0].body = new Tree[1];
+ global.units[0].body[0] = global.treeGen.Apply(
+ global.treeGen.mkRef(pos, module.thisType(), method),
+ new Tree[] { global.make.Literal(pos, args) });
+ }
+
+ //########################################################################
+ // Private Methods
+
+ private Symbol getModule(Symbol module, Name name) {
+ Symbol symbol = module.lookup(name);
+ if (symbol == Symbol.NONE || symbol.isModule()) return symbol;
+ switch (symbol.type()) {
+ case OverloadedType(Symbol[] alts, _):
+ for (int k = 0; k < alts.length; k++)
+ if (alts[k].isModule()) return alts[k];
+ }
+ return Symbol.ERROR;
+ }
+
+ private Symbol getMethod(Symbol module, Name name, Type type) {
+ Symbol symbol = module.lookup(name);
+ if (symbol == Symbol.NONE || isMethod(symbol, type)) return symbol;
+ switch (symbol.type()) {
+ case OverloadedType(Symbol[] alts, _):
+ for (int k = 0; k < alts.length; k++)
+ if (isMethod(alts[k], type)) return alts[k];
+ }
+ return Symbol.ERROR;
+ }
+
+ private boolean isMethod(Symbol symbol, Type type) {
+ return symbol.isMethod() && symbol.type().equals(type);
+ }
+
+ private void error(String message) {
+ global.reporter.error(product + ": " + message);
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/Environment.java b/sources/scala/tools/scalai/Environment.java
new file mode 100644
index 0000000000..51867abca0
--- /dev/null
+++ b/sources/scala/tools/scalai/Environment.java
@@ -0,0 +1,205 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Environment.java,v 1.13 2002/10/01 16:14:07 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import scalac.ast.Tree.ClassDef;
+import scalac.symtab.Symbol;
+import scalac.symtab.Type;
+import scalac.symtab.Scope;
+import scalac.symtab.Scope.SymbolIterator;
+import scalac.util.Debug;
+
+public class Environment {
+
+ //########################################################################
+ // Private Fields
+
+ private final Compiler compiler;
+ private final JavaMirror mirror;
+ private final Map/*<Symbol,ClassDef>*/ classdefs;
+ private final Map/*<Symbol,Template>*/ templates;
+ private final Map/*<Symbol,Function>*/ functions;
+ private final Map/*<Symbol,Variable>*/ variables;
+ private final Map/*<Symbol,Override>*/ overrides;
+
+ //########################################################################
+ // Public Constructors
+
+ public Environment(Compiler compiler, JavaMirror mirror) {
+ this.compiler = compiler;
+ this.mirror = mirror;
+ this.classdefs = new HashMap();
+ this.templates = new HashMap();
+ this.functions = new HashMap();
+ this.variables = new HashMap();
+ this.overrides = new HashMap();
+ }
+
+ //########################################################################
+ // Public Methods - insert
+
+ public ClassDef insertClassDef(Symbol symbol, ClassDef classdef) {
+ assert symbol.isType() : Debug.show(symbol);
+ assert Debug.log("insert classdef", symbol);
+ Object value = classdefs.put(symbol, classdef);
+ assert value == null : Debug.show(symbol);
+ assert !templates.containsKey(symbol) : Debug.show(symbol);
+ return classdef;
+ }
+
+ private Template insertTemplate(Symbol symbol, Template template) {
+ assert symbol.isType() : Debug.show(symbol);
+ assert Debug.log("insert template", symbol);
+ Object value = templates.put(symbol, template);
+ assert !classdefs.containsKey(symbol) : Debug.show(symbol);
+ assert value == null : Debug.show(symbol);
+ return template;
+ }
+
+ public Function insertFunction(Symbol symbol, Function function) {
+ assert symbol.isTerm() : Debug.show(symbol);
+ assert Debug.log("insert function", symbol);
+ Object value = functions.put(symbol, function);
+ assert value == null : Debug.show(symbol);
+ return function;
+ }
+
+ public Variable insertVariable(Symbol symbol, Variable variable) {
+ assert symbol.isTerm() : Debug.show(symbol);
+ assert Debug.log("insert variable", symbol);
+ Object value = variables.put(symbol, variable);
+ assert value == null : Debug.show(symbol);
+ return variable;
+ }
+
+ public Override insertOverride(Symbol symbol, Override override) {
+ assert symbol.isTerm() : Debug.show(symbol);
+ assert Debug.log("insert override", symbol);
+ Object value = overrides.put(symbol, override);
+ assert value == null : Debug.show(symbol);
+ return override;
+ }
+
+ //########################################################################
+ // Public Methods - lookup
+
+ public Template lookupTemplate(Symbol symbol) {
+ assert symbol.isType() : Debug.show(symbol);
+ Object value = templates.get(symbol);
+ if (value != null) return (Template)value;
+ if (symbol.isJava()) {
+ Template template = Template.JavaClass(mirror.getClass(symbol));
+ return insertTemplate(symbol, template);
+ } else {
+ return loadTemplate(symbol);
+ }
+ }
+
+ public Function lookupFunction(Symbol symbol) {
+ assert symbol.isTerm() : Debug.show(symbol);
+ Object value = functions.get(symbol);
+ if (value != null) return (Function)value;
+ if (symbol.isJava()) {
+ Function function = symbol.isConstructor() ?
+ Function.JavaConstructor(mirror.getConstructor(symbol)) :
+ Function.JavaMethod(mirror.getMethod(symbol));
+ return insertFunction(symbol, function);
+ } else {
+ return (Function)loadOwnerThenGet("function", symbol, functions);
+ }
+ }
+
+ public Variable lookupVariable(Symbol symbol) {
+ assert symbol.isTerm() : Debug.show(symbol);
+ Object value = variables.get(symbol);
+ if (value != null) return (Variable)value;
+ if (symbol.isJava()) {
+ Variable variable = Variable.JavaField(mirror.getField(symbol));
+ return insertVariable(symbol, variable);
+ } else {
+ return (Variable)loadOwnerThenGet("variable", symbol, variables);
+ }
+ }
+
+ public Override lookupOverride(Symbol symbol) {
+ assert symbol.isTerm() : Debug.show(symbol);
+ Object value = overrides.get(symbol);
+ if (value != null) return (Override)value;
+ return loadOwnerOverridesThenGet(symbol);
+ }
+
+ //########################################################################
+ // Private Methods - template loading
+
+ private Object loadOwnerThenGet(String what, Symbol symbol, Map table) {
+ loadOwner(what, symbol);
+ Object value = table.get(symbol);
+ assert value != null : Debug.show(symbol);
+ return value;
+ }
+
+ private void loadOwner(String what, Symbol symbol) {
+ assert Debug.log("search " + what, symbol);
+ assert symbol.owner().isType() : Debug.show(symbol);
+ assert!symbol.owner().isJava() : Debug.show(symbol);
+ loadTemplate(symbol.owner());
+ }
+
+ private Template loadTemplate(Symbol symbol) {
+ Object test1 = classdefs.remove(symbol);
+ if (test1 != null) return loadTemplate(symbol, (ClassDef)test1);
+ loadOwner("template", symbol);
+ Object test2 = classdefs.remove(symbol);
+ if (test2 != null) return loadTemplate(symbol, (ClassDef)test2);
+ Object value = templates.get(symbol);
+ assert value != null : Debug.show(symbol);
+ return (Template)value;
+ }
+
+ private Template loadTemplate(Symbol symbol, ClassDef classdef) {
+ Template template = Template.Global(compiler.load(symbol, classdef));
+ return insertTemplate(symbol, template);
+ }
+
+ //########################################################################
+ // Private Methods - override loading
+
+ private Override loadOwnerOverridesThenGet(Symbol symbol) {
+ assert Debug.log("search override", symbol);
+ assert symbol.owner().isType() : Debug.show(symbol);
+ loadTemplateOverrides(symbol.owner());
+ Object value = overrides.get(symbol);
+ assert value != null : Debug.show(symbol);
+ return (Override)value;
+ }
+
+ private void loadTemplateOverrides(Symbol symbol) {
+ Type[] bases = symbol.parents();
+ SymbolIterator i = new Scope.UnloadIterator(symbol.members().iterator());
+ while (i.hasNext()) loadMethodOverride(bases, i.next());
+ }
+
+ private void loadMethodOverride(Type[] bases, Symbol symbol) {
+ if (!symbol.isMethod()) return;
+ Override override = Override.empty().insert(symbol);
+ if (symbol.isJava()) override.insert(mirror.getMethod(symbol));
+ for (int i = 0; i < bases.length; i++) {
+ Symbol overridden = symbol.overriddenSymbol(bases[i]);
+ if (overridden == Symbol.NONE) continue;
+ override.insert(lookupOverride(overridden));
+ }
+ insertOverride(symbol, override);
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/Evaluator.java b/sources/scala/tools/scalai/Evaluator.java
new file mode 100644
index 0000000000..07b5b025f8
--- /dev/null
+++ b/sources/scala/tools/scalai/Evaluator.java
@@ -0,0 +1,538 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Evaluator.java,v 1.40 2002/10/04 15:37:10 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+
+import scala.runtime.RunTime;
+
+import scalac.symtab.Symbol;
+import scalac.util.Debug;
+
+public class Evaluator {
+
+ //########################################################################
+ // Public Interfaces
+
+ // !!! remove
+ public static interface Levels {
+ public static final int CLASS = 0;
+ public static final int ARGS = 1; // !!! use PARAM ?
+ public static final int BODY = 2;
+ }
+
+ //########################################################################
+ // Private Classes
+
+ // !!! remove ?
+ private static class LabelException extends EvaluatorException {
+
+ public final Symbol symbol;
+ public final Object[] args;
+
+ public LabelException(Symbol symbol, Object[] args) {
+ super(null);
+ this.symbol = symbol;
+ this.args = args;
+ }
+ }
+
+ //########################################################################
+ // Private Fields
+
+ private final Object[][] variables;
+ private Object self;
+
+ //########################################################################
+ // Public Constructors
+
+ public Evaluator() {
+ this.variables = new Object[3][];
+ this.variables[Levels.CLASS] = null;
+ this.variables[Levels.ARGS] = null;
+ this.variables[Levels.BODY] = null;
+ this.self = null;
+ }
+
+ //########################################################################
+ // Public Methods
+
+ public Object evaluate(CodeContainer code) {
+ // !!! System.out.println("!!! EVALUATE");
+ // !!! System.out.println("!!! size = " + size);
+ // !!! System.out.println("!!! code.symbol = " +Debug.show(code.symbol));
+ // !!! System.out.println("!!! code.stacksize = " + code.stacksize);
+ // !!! System.out.println("!!! code.code = " + code.code);
+ // !!! System.out.println("!!! ");
+ return evaluate(code, null, new Object[0]);
+ }
+
+ public Object evaluate(CodePromise code, Object object, Object[] args) {
+ return evaluate(code.force(), object, args);
+ }
+
+ public Object evaluate(CodeContainer code, Object object, Object[] args) {
+ try {
+ // !!! System.out.println("!!! EVALUATE");
+ // !!! System.out.println("!!! code.symbol = " +Debug.show(code.symbol));
+ // !!! for (int i = 0; i < args.length; i++) {
+ // !!! System.out.println("!!! arg" + i + " = " + Debug.show(args[i]));
+ // !!! }
+ // !!! System.out.println("!!! code.stacksize = " + code.stacksize);
+ // !!! System.out.println("!!! code.code = " + code.code);
+ // !!! System.out.println("!!! ");
+
+ Object backup_self = self;
+ Object[] backup_args = variables[Levels.ARGS];
+ Object[] backup_body = variables[Levels.BODY];
+ self = object;
+ variables[Levels.ARGS] = args;
+ variables[Levels.BODY] = new Object[code.stacksize];
+ Object result = evaluate(code.code);
+ self = backup_self;
+ variables[Levels.ARGS] = backup_args;
+ variables[Levels.BODY] = backup_body;
+
+ // !!! System.out.println("!!! RETURN");
+ // !!! System.out.println("!!! code.symbol = " +Debug.show(code.symbol));
+ // !!! System.out.println("!!! result.class = " + Debug.show(result));
+
+ return result;
+ } catch (EvaluatorException exception) {
+ throw exception;
+ } catch (Error exception) {
+ throw exception;
+ } catch (Throwable exception) {
+ throw Debug.abort(exception);
+ }
+ }
+
+ //########################################################################
+ // Private Methods - evaluate
+
+ private Object evaluate(Code code) {
+ switch (code) {
+
+ case Block(Code[] stats, Code value):
+ for (int i = 0; i < stats.length; i++) evaluate(stats[i]);
+ return evaluate(value);
+
+ case Label(Symbol symbol, Variable[] variables, Code expression):
+ while (true)
+ try {
+ return evaluate(expression);
+ } catch (LabelException exception) {
+ if (exception.symbol != symbol) throw exception;
+ for (int i = 0; i < variables.length; i++) {
+ // !!! null
+ store(null, variables[i], exception.args[i]);
+ }
+ }
+
+ case If(Code cond, Code thenp, Code elsep):
+ Object value = evaluate(cond);
+ assert value instanceof Boolean : value.getClass();
+ return evaluate(((Boolean)value).booleanValue() ? thenp : elsep);
+
+ case Literal(Object value):
+ return value;
+
+ case Load(Code target, Variable variable):
+ return load(evaluate(target), variable);
+
+ case Store(Code target, Variable variable, Code expression):
+ store(evaluate(target), variable, evaluate(expression));
+ return RunTime.box();
+
+ case Invoke(Code target, Function function, Code[] parameters, int pos, Symbol method):
+ Object object = evaluate(target);
+ Object[] args = new Object[parameters.length];
+ for (int i = 0; i < args.length; i++) {
+ args[i] = evaluate(parameters[i]);
+ }
+ try { // !!! indent
+ return invoke(object, function, args);
+ } catch (EvaluatorException exception) {
+ exception.addCall(pos, method);
+ throw exception;
+ }
+
+ case Create(ScalaTemplate template):
+ return invoke(null, template.getConstructor(),
+ new Object[] {template.getHandler()});
+
+ case Box(Code value):
+ return box(evaluate(value));
+
+ case IsScala(Code target, Symbol symbol):
+ Object object = evaluate(target);
+ Symbol actual = getScalaObject(object).template.getSymbol();
+ return new Boolean(actual.isSubClass(symbol));
+
+ case IsJava(Code target, Class clasz):
+ Object object = evaluate(target);
+ return new Boolean(clasz.isInstance(object));
+
+ case Or(Code lf, Code rg):
+ Object object = evaluate(lf);
+ assert object instanceof scala.Boolean : object.getClass();
+ boolean value = ((scala.Boolean)object).asBoolean();
+ if (value) return new Boolean(value);
+ return evaluate(rg);
+
+ case And(Code lf, Code rg):
+ Object object = evaluate(lf);
+ assert object instanceof scala.Boolean : object.getClass();
+ boolean value = ((scala.Boolean)object).asBoolean();
+ if (!value) return new Boolean(value);
+ return evaluate(rg);
+
+ case Null:
+ return null;
+
+ case Self:
+ // !!! System.out.println("!!! Self: " + Debug.show(self));
+ return self;
+
+ default:
+ throw Debug.abort("illegal code", code);
+ }
+ }
+
+ //########################################################################
+ // Private Methods - invoke
+
+ private Object invoke(Object object, Function function, Object[] args) {
+ switch (function) {
+
+ case Global(CodePromise code):
+ return evaluate(code, object, args);
+
+ case Member(Symbol symbol):
+ // !!! handle case where object is null
+ return getScalaObject(object).invoke(object, symbol, args);
+
+ case Label(Symbol symbol):
+ throw new LabelException(symbol, args);
+
+ case JavaConstructor(Constructor constructor):
+ return invoke(object, constructor, args);
+
+ case JavaMethod(Method method):
+ return invoke(object, method, args);
+
+ case Pos:
+ if (object instanceof scala.Int) {
+ int value = ((scala.Int)object).asInt();
+ return new Integer(value);
+ } else if (object instanceof scala.Long) {
+ long value = ((scala.Long)object).asLong();
+ return new Long(value);
+ } else if (object instanceof scala.Float) {
+ float value = ((scala.Float)object).asFloat();
+ return new Float(value);
+ } else {
+ double value = ((scala.Double)object).asDouble();
+ return new Double(value);
+ }
+
+ case Neg:
+ if (object instanceof scala.Int) {
+ int value = ((scala.Int)object).asInt();
+ return new Integer(-value);
+ } else if (object instanceof scala.Long) {
+ long value = ((scala.Long)object).asLong();
+ return new Long(-value);
+ } else if (object instanceof scala.Float) {
+ float value = ((scala.Float)object).asFloat();
+ return new Float(-value);
+ } else {
+ double value = ((scala.Double)object).asDouble();
+ return new Double(-value);
+ }
+
+ case Throw:
+ assert args.length == 0 : Debug.show(args);
+ assert object instanceof Throwable : object.getClass();
+ throw new EvaluatorException((Throwable)object);
+
+ case StringPlus:
+ assert args.length == 1 : Debug.show(args);
+ //assert object instanceof String : object.getClass().getName();
+ return (String.valueOf(object)).concat(String.valueOf(args[0]));
+
+ case EqEq:
+ assert args.length == 1 : Debug.show(args);
+ return object == null ? new Boolean(args[0] == null) : isScalaObject(object) ? getScalaObject(object).invoke(object, scalac.Global.instance.definitions.EQEQ, args) : new Boolean(object.equals(args[0])); // !!!
+
+ case BangEq:
+ assert args.length == 1 : Debug.show(args);
+ return object == null ? new Boolean(args[0] != null) : isScalaObject(object) ? getScalaObject(object).invoke(object, scalac.Global.instance.definitions.BANGEQ, args) : new Boolean(!object.equals(args[0])); // !!!
+
+ case HashCode:
+ assert args.length == 0 : Debug.show(args);
+ return new Integer(getScalaObject(object).hashCode());
+
+ case ToString:
+ assert args.length == 0 : Debug.show(args);
+ return getScalaObject(object).toString();
+
+ default:
+ throw Debug.abort("illegal function", function);
+ }
+ }
+
+ private Object invoke(Object object, Constructor constructor,Object[]args){
+ try {
+ // !!! System.out.println("!!! object " + (object == null ? "null" : object.getClass().getName()));
+ // !!! System.out.println("!!! constr " + constructor);
+ // !!! System.out.println("!!! nbargs " + args.length);
+ return constructor.newInstance(args);
+ } catch (ExceptionInInitializerError exception) {
+ return exception(exception.getException());
+ } catch (InvocationTargetException exception) {
+ return exception(exception.getTargetException());
+ } catch (InstantiationException exception) {
+ String msg1 = "\n object = " + Debug.show(object);
+ String msg2 = "\n constr = " + Debug.show(constructor);
+ String msg3 = "\n args = " + Debug.show(args);
+ throw Debug.abort(msg1 + msg2 + msg3, exception);
+ } catch (IllegalAccessException exception) {
+ String msg1 = "\n object = " + Debug.show(object);
+ String msg2 = "\n constr = " + Debug.show(constructor);
+ String msg3 = "\n args = " + Debug.show(args);
+ throw Debug.abort(msg1 + msg2 + msg3, exception);
+ } catch (IllegalArgumentException exception) {
+ String msg1 = "\n object = " + Debug.show(object);
+ String msg2 = "\n constr = " + Debug.show(constructor);
+ String msg3 = "\n args = " + Debug.show(args);
+ throw Debug.abort(msg1 + msg2 + msg3, exception);
+ }
+ }
+
+ private Object invoke(Object object, Method method, Object[] args) {
+ try {
+ return method.invoke(object, args);
+ } catch (NullPointerException exception) {
+ return exception(exception);
+ } catch (ExceptionInInitializerError exception) {
+ return exception(exception.getException());
+ } catch (InvocationTargetException exception) {
+ return exception(exception.getTargetException());
+ } catch (IllegalAccessException exception) {
+ String msg1 = "\n object = " + Debug.show(object);
+ String msg2 = "\n method = " + Debug.show(method);
+ String msg3 = "\n args = " + Debug.show(args);
+ throw Debug.abort(msg1 + msg2 + msg3, exception);
+ } catch (IllegalArgumentException exception) {
+ String msg1 = "\n object = " + Debug.show(object);
+ String msg2 = "\n method = " + Debug.show(method);
+ String msg3 = "\n args = " + Debug.show(args);
+ throw Debug.abort(msg1 + msg2 + msg3, exception);
+ }
+ }
+
+ //########################################################################
+ // Private Methods - store
+
+ // !!! return void ?
+ private Object store(Object object, Variable variable, Object value) {
+ switch (variable) {
+
+ case Global(_):
+ return ((Variable.Global)variable).value = value;
+
+ case Context(int level, int index):
+ // !!! System.out.println("!!! store Context: level = " + level + ", index = " + index);
+ return variables[level][index] = value;
+
+ case Member(int index):
+ // !!! handle case where object is null
+ // !!! System.out.println("!!! store Member: index = " + index + ", length = " + getScalaObject(object).variables.length);
+ return getScalaObject(object).variables[index] = value;
+
+ case JavaField(Field field):
+ return store(object, field, value);
+
+ default:
+ throw Debug.abort("illegal variable", variable);
+ }
+ }
+
+ private Object store(Object object, Field field, Object value) {
+ try {
+ field.set(object, value);
+ return value;
+ } catch (NullPointerException exception) {
+ return exception(exception);
+ } catch (ExceptionInInitializerError exception) {
+ return exception(exception.getException());
+ } catch (IllegalAccessException exception) {
+ String msg1 = "\n object = " + Debug.show(object);
+ String msg2 = "\n field = " + Debug.show(field);
+ String msg3 = "\n value = " + Debug.show(value);
+ throw Debug.abort(msg1 + msg2 + msg3, exception);
+ } catch (IllegalArgumentException exception) {
+ String msg1 = "\n object = " + Debug.show(object);
+ String msg2 = "\n field = " + Debug.show(field);
+ String msg3 = "\n value = " + Debug.show(value);
+ throw Debug.abort(msg1 + msg2 + msg3, exception);
+ }
+ }
+
+ //########################################################################
+ // Private Methods - load
+
+ private Object load(Object object, Variable variable) {
+ switch (variable) {
+
+ case Global(Object value):
+ return value;
+
+ case Context(int level, int index):
+ return variables[level][index];
+
+ case Module(CodePromise body, Object value):
+ if (value == null) {
+ // !!!
+ ((Variable.Module)variable).value = value = evaluate(body.force().code);
+ ((Variable.Module)variable).body = null;
+ }
+ return value;
+
+ case Member(int index):
+ // !!! handle case where object is null
+ // !!! System.out.println("!!! loadScala: self = " + Debug.show(object) + ", index = " + index);
+ // !!! System.out.println("!!! loadScala: value = " + Debug.show(getScalaObject(object).variables[index]));
+ return getScalaObject(object).variables[index];
+
+ case JavaField(Field field):
+ return load(object, field);
+
+ default:
+ throw Debug.abort("illegal variable", variable);
+ }
+ }
+
+ private Object load(Object object, Field field) {
+ try {
+ return field.get(object);
+ } catch (NullPointerException exception) {
+ return exception(exception);
+ } catch (ExceptionInInitializerError exception) {
+ return exception(exception.getException());
+ } catch (IllegalAccessException exception) {
+ String msg1 = "\n object = " + Debug.show(object);
+ String msg2 = "\n field = " + Debug.show(field);
+ throw Debug.abort(msg1 + msg2, exception);
+ } catch (IllegalArgumentException exception) {
+ String msg1 = "\n object = " + Debug.show(object);
+ String msg2 = "\n field = " + Debug.show(field);
+ throw Debug.abort(msg1 + msg2, exception);
+ }
+ }
+
+ //########################################################################
+ // Private Methods - box
+
+ // !!!
+ private final Class Boolean_class = Boolean.class;
+ private final Class Byte_class = Byte.class;
+ private final Class Short_class = Short.class;
+ private final Class Character_class = Character.class;
+ private final Class Integer_class = Integer.class;
+ private final Class Long_class = Long.class;
+ private final Class Float_class = Float.class;
+ private final Class Double_class = Double.class;
+
+ // !!!
+ private final Class boolean_class = Boolean.TYPE;
+ private final Class byte_class = Byte.TYPE;
+ private final Class short_class = Short.TYPE;
+ private final Class char_class = Character.TYPE;
+ private final Class int_class = Integer.TYPE;
+ private final Class long_class = Long.TYPE;
+ private final Class float_class = Float.TYPE;
+ private final Class double_class = Double.TYPE;
+
+ private Object box(Object value) {
+ // !!! check
+ // !!! System.out.println("!!! box: ");
+ if (value == null) return null;
+ Class type = value.getClass();
+ if (type == Boolean_class)
+ return RunTime.box(((Boolean)value).booleanValue());
+ if (type == Byte_class)
+ return RunTime.box(((Byte)value).byteValue());
+ if (type == Short_class)
+ return RunTime.box(((Short)value).shortValue());
+ if (type == Character_class)
+ return RunTime.box(((Character)value).charValue());
+ if (type == Integer_class)
+ return RunTime.box(((Integer)value).intValue());
+ if (type == Long_class)
+ return RunTime.box(((Long)value).longValue());
+ if (type == Float_class)
+ return RunTime.box(((Float)value).floatValue());
+ if (type == Double_class)
+ return RunTime.box(((Double)value).doubleValue());
+ if (type.isArray()) {
+ type = type.getComponentType();
+ if (type == boolean_class) return RunTime.box((boolean[])value);
+ if (type == byte_class) return RunTime.box((byte[])value);
+ if (type == short_class) return RunTime.box((short[])value);
+ if (type == char_class) return RunTime.box((char[])value);
+ if (type == int_class) return RunTime.box((int[])value);
+ if (type == long_class) return RunTime.box((long[])value);
+ if (type == float_class) return RunTime.box((float[])value);
+ if (type == double_class) return RunTime.box((double[])value);
+ return RunTime.box((Object[])value);
+ }
+ return value;
+ }
+
+ //########################################################################
+ // Private Methods - !!!
+
+ private boolean isScalaObject(Object object) {
+ return Proxy.isProxyClass(object.getClass()); // !!! add more checks ?
+ }
+
+ private ScalaObject getScalaObject(Object object) {
+ if (object == null)
+ return (ScalaObject)exception(new NullPointerException()); // !!!
+ assert object instanceof Proxy : object.getClass();
+ return (ScalaObject)Proxy.getInvocationHandler(object);
+ }
+
+ private Object exception(Throwable exception) {
+ // !!! return an exception result
+ if (exception instanceof EvaluatorException) {
+ throw (EvaluatorException)exception;
+ }
+ if (exception instanceof Error) {
+ throw (Error)exception;
+ }
+ throw new EvaluatorException(exception, new Error());
+ }
+
+ // !!! remove ?
+ private Error abort(Exception exception) {
+ // !!! return an abort result ?
+ return Debug.abort(exception);
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/EvaluatorException.java b/sources/scala/tools/scalai/EvaluatorException.java
new file mode 100644
index 0000000000..4853bbcc9f
--- /dev/null
+++ b/sources/scala/tools/scalai/EvaluatorException.java
@@ -0,0 +1,86 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id$
+
+package scalai;
+
+import java.util.Stack;
+
+import scalac.Global;
+import scalac.ast.parser.Sourcefile;
+import scalac.symtab.Symbol;
+import scalac.util.Position;
+
+public class EvaluatorException extends RuntimeException {
+
+ //########################################################################
+ // Private Fields
+
+ private final Throwable exception;
+ private final Throwable cut;
+ private final Stack stack; // !!! rename ?
+ private final Stack symbols;
+
+ //########################################################################
+ // Public Constructors
+
+ public EvaluatorException(Throwable exception) {
+ this(exception, null);
+ }
+
+ public EvaluatorException(Throwable exception, Throwable cut) {
+ this.exception = exception;
+ this.cut = cut;
+ this.stack = new Stack();
+ this.symbols = new Stack();
+ }
+
+ //########################################################################
+ // Public Methods
+
+ public void addCall(int pos, Symbol symbol) {
+ stack.push(new Integer(pos));
+ symbols.push(symbol);
+ }
+
+ public String mkString(Global global) {
+ StringBuffer buffer = new StringBuffer();
+ // !!! if (exception != null)buffer.append(Strings.stackTrace(exception));
+ buffer.append(exception.toString());
+ for (int i = 0; i < stack.size(); i++) {
+ buffer.append('\n');
+ int pos = ((Integer)stack.elementAt(i)).intValue();
+ buffer.append(" at " +
+ context(global, (Symbol)symbols.elementAt(i)) +
+ "(" + Sourcefile.files[Position.file(pos)] + ":" +
+ Position.line(pos) + ")");
+ }
+ return buffer.toString();
+ }
+
+ // !!! remove ? modify ?
+ public String toString() {
+ return getClass().getName() + ": " + exception;
+ }
+
+ //########################################################################
+ // Private Methods
+
+ private String context(Global global, Symbol symbol) {
+ if (symbol == null) return "<top-level>";
+ assert !symbol.isClass() : symbol.defString();
+ Symbol owner = symbol.owner();
+ if (owner == global.definitions.ROOT_CLASS
+ || symbol.owner() == Symbol.NONE) // !!! || ...
+ {
+ return symbol.name.toString();
+ }
+ return owner.fullName() + "." + symbol.name;
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/EvaluatorResult.java b/sources/scala/tools/scalai/EvaluatorResult.java
new file mode 100644
index 0000000000..f3dd61121a
--- /dev/null
+++ b/sources/scala/tools/scalai/EvaluatorResult.java
@@ -0,0 +1,21 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id$
+
+package scalai;
+
+public class EvaluatorResult {
+
+ //########################################################################
+ // Public Cases
+
+ case Void;
+ case Value(Object value);
+ case Error(EvaluatorException exception);
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/ExpressionCompiler.java b/sources/scala/tools/scalai/ExpressionCompiler.java
new file mode 100644
index 0000000000..9e864f98a6
--- /dev/null
+++ b/sources/scala/tools/scalai/ExpressionCompiler.java
@@ -0,0 +1,288 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: ExpressionCompiler.java,v 1.16 2002/10/04 15:37:10 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+
+import scalac.ast.Tree;
+import scalac.symtab.Symbol;
+import scalac.symtab.Definitions;
+import scalac.util.Debug;
+import scalac.util.Name;
+
+public class ExpressionCompiler {
+
+ //########################################################################
+ // Private Fields
+
+ private final Definitions definitions;
+ private final Constants constants;
+ private final ExpressionContext context;
+
+ //########################################################################
+ // Public Constructors
+
+ public ExpressionCompiler(Definitions definitions, Constants constants, ExpressionContext context, Symbol[] params) {
+ this.definitions = definitions;
+ this.constants = constants;
+ this.context = context;
+ for (int i = 0; i < params.length; i++) {
+ context.insertVariable(params[i], Variable.Context(Evaluator.Levels.ARGS,i));
+ }
+ }
+
+ //########################################################################
+ // Public Methods
+
+ public CodeContainer compile(Tree tree) {
+ Code code = compute(tree);
+ return new CodeContainer(context.owner(), code, context.stackmax());
+ }
+
+ public CodeContainer compile(ArrayList items) {
+ Code value = Code.Literal(constants.literal());
+ CodeBuffer buffer = new CodeBuffer();
+ for (int i = 0, m = items.size(); i < m;) {
+ if (i > 0) buffer.append(value);
+ Object item = items.get(i++);
+ value = compute((Tree)item);
+ }
+ Code code = buffer.code(value);
+ return new CodeContainer(context.owner(), code, context.stackmax());
+ }
+
+ //########################################################################
+ // Private Methods - declare
+
+ private void declare(Tree tree, CodeBuffer buffer) {
+ switch (tree) {
+
+ case Empty:
+ return;
+
+ case ValDef(_, _, _, Tree body):
+ Symbol symbol = tree.symbol();
+ Variable variable = Variable.Context(Evaluator.Levels.BODY, context.push());
+ context.insertVariable(symbol, variable);
+ // !!! this should be done in an earlier phase
+ Code value = body != Tree.Empty ?
+ compute(body) : Code.Literal(constants.zero(symbol.type()));
+ buffer.append(Code.Store(Code.Self, variable, value));
+ return;
+
+ default:
+ buffer.append(compute(tree));
+ return;
+ }
+ }
+
+ //########################################################################
+ // Private Methods - compute
+
+ private Code[] compute(Tree[] trees) {
+ Code[] codes = new Code[trees.length];
+ for (int i = 0; i < codes.length; i++) codes[i] = compute(trees[i]);
+ return codes;
+ }
+
+ private Code compute(Tree tree) {
+ switch (tree) {
+
+ case LabelDef(Tree[] params, Tree body):
+ Symbol symbol = tree.symbol();
+ Variable[] vars = new Variable[params.length];
+ for (int i = 0; i < params.length; i++) {
+ vars[i] = context.lookupVariable(params[i].symbol());
+ // !!!
+ assert vars[i] instanceof Variable.Context:Debug.show(vars[i]);
+ }
+ context.insertLabel(symbol);
+ return Code.Label(symbol, vars, compute(body));
+
+ case Block(Tree[] stats):
+ assert stats.length > 0;
+ CodeBuffer buffer = new CodeBuffer();
+ int stacksize = context.stacksize();
+ for (int i = 0; i < stats.length - 1; i++)
+ declare(stats[i], buffer);
+ Code value = compute(stats[stats.length - 1]);
+ context.stacksize(stacksize);
+ return buffer.code(value);
+
+ case Assign(Tree lhs, Tree rhs):
+ return store(lhs, lhs.symbol(), compute(rhs));
+
+ case If(Tree cond, Tree thenp, Tree elsep):
+ return Code.If(compute(cond), compute(thenp),
+ // !!! can we remove this test ?
+ elsep == Tree.Empty ? Code.Literal(constants.literal()) : compute(elsep));
+
+ case New(Tree.Template(Tree[] bases, Tree[] body)): // !!!
+ assert bases.length == 1 : Debug.show(tree);
+ assert body.length == 0 : Debug.show(tree);
+ Code code = compute(bases[0]);
+ switch (context.lookupTemplate(tree.type().symbol())) {
+ case Global(ScalaTemplate template):
+ assert code instanceof Code.Invoke : Debug.show(code);
+ Code.Invoke invoke = (Code.Invoke)code;
+ // !!! correct ?
+ assert invoke.target == Code.Self | invoke.target == Code.Null : Debug.show(code);
+ invoke.target = Code.Create(template);
+ }
+ return code;
+
+ case Apply(TypeApply(Tree tfun, Tree[] targs), Tree[] vargs):
+ assert vargs.length == 0 : Debug.show(tree);
+ return tapply(tfun, tfun.symbol(), targs);
+
+ case Apply(Tree vfun, Tree[] vargs):
+ return vapply(vfun, vfun.symbol(), vargs);
+
+ case This(_):
+ return Code.Self;
+
+ case Literal(Object value):
+ return Code.Literal(value);
+
+ default:
+ return load(tree, tree.symbol());
+ }
+ }
+
+ private Code object(Tree tree) {
+ switch (tree) {
+
+ case Select(Super(_), _):
+ return Code.Self;
+
+ case Select(Tree expr, _):
+ return compute(expr);
+
+ case Ident(_):
+ return Code.Self;
+
+ default:
+ throw Debug.abort("illegal tree", tree);
+ }
+ }
+
+ //########################################################################
+ // Private Methods - apply
+
+ private Code tapply(Tree target, Symbol symbol, Tree[] trees) {
+ Code object = object(target);
+ if (symbol == definitions.AS) {
+ assert trees.length == 1 : Debug.show(trees);
+ // !!! some AS should be kept; they might fail
+ return object;
+ }
+ if (symbol == definitions.IS) {
+ assert trees.length == 1 : Debug.show(trees);
+ assert trees[0].hasSymbol() : trees[0];
+ Symbol expect = trees[0].symbol();
+ // !!! BUG: expect is null for .is[Int]
+ assert expect != null : trees[0];
+ // !!! System.out.println("!!! IS " + expect);
+ Template template = context.lookupTemplate(expect);
+ switch (template) {
+
+ case Global(_) :
+ return Code.IsScala(object, expect);
+
+ case JavaClass(Class clasz):
+ return Code.IsJava(object, clasz);
+
+ default:
+ throw Debug.abort("illegal template", template);
+ }
+ }
+ throw Debug.abort("unknown method", symbol);
+ }
+
+ // !!! only used for the hack in vapply => remove !
+ private static final Name plus_N = Name.fromString("$plus");
+ private static final Name minus_N = Name.fromString("$minus");
+
+ private Code vapply(Tree target, Symbol symbol, Tree[] trees) {
+ // !!! optimize ?
+ Code object = object(target);
+ if (symbol == definitions.BARBAR()) {
+ return Code.Or(object, compute(trees[0]));
+ }
+ if (symbol == definitions.AMPAMP()) {
+ return Code.And(object, compute(trees[0]));
+ }
+ // !!! System.out.println("!!! method: " + Debug.show(symbol));
+ // !!! System.out.println("!!! -owner: " + Debug.show(symbol.owner()));
+ Function function = context.lookupFunction(symbol);
+ if (trees.length == 0
+ && (symbol.name == plus_N || symbol.name == minus_N)
+ // !!! the following line does not work. why? (because of erasure?)
+ // !!! symbol.owner().isSubClass(definitions.DOUBLE_CLASS))
+ && (
+ symbol.owner().isSubClass(definitions.INT_CLASS) ||
+ symbol.owner().isSubClass(definitions.LONG_CLASS) ||
+ symbol.owner().isSubClass(definitions.FLOAT_CLASS) ||
+ symbol.owner().isSubClass(definitions.DOUBLE_CLASS)))
+ {
+ function = symbol.name == plus_N ? Function.Pos : Function.Neg;
+ }
+ switch (target) {
+ case Select(Super(_), _):
+ Template template = context.lookupTemplate(symbol.owner());
+ switch (template) {
+ case Global(ScalaTemplate template_):
+ function = Function.Global(template_.getMethod(symbol));
+ break;
+
+ case JavaClass(Class clasz):
+ throw Debug.abort("!!! illegal super on java class", symbol);
+
+ default:
+ throw Debug.abort("illegal template", template);
+ }
+ }
+ Code[] args = compute(trees);
+ return Code.Invoke(object, function, args, target.pos,context.owner());
+ }
+
+ //########################################################################
+ // Private Methods - load & store
+
+ private Code load(Tree target, Symbol symbol) {
+ // !!! remove this hack, and argument "from"
+ if (symbol.isMethod()) { // !!! Kinds.
+ // !!!
+ if (symbol == definitions.NULL) return Code.Null;
+ return vapply(target, symbol, Tree.EMPTY_ARRAY);
+ }
+
+ // !!! return something ? raise exception ?
+ if (!symbol.isValue()) return Code.Null;
+
+ // !!! we should remove this test and only test if is JAVA
+ if (symbol.isModule()) {
+ // !!! why don't we use type() ?
+ Symbol type = symbol.info().symbol(); // !!! simplify ?
+ switch (context.lookupTemplate(type)) {
+ case JavaClass(Class clasz): return Code.Literal(clasz);
+ }
+ }
+
+ return Code.Load(object(target), context.lookupVariable(symbol));
+ }
+
+ private Code store(Tree target, Symbol symbol, Code value) {
+ return Code.Store(object(target),context.lookupVariable(symbol),value);
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/ExpressionContext.java b/sources/scala/tools/scalai/ExpressionContext.java
new file mode 100644
index 0000000000..dfc47c4401
--- /dev/null
+++ b/sources/scala/tools/scalai/ExpressionContext.java
@@ -0,0 +1,114 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: ExpressionContext.java,v 1.2 2002/06/05 09:05:56 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import scalac.symtab.Symbol;
+import scalac.util.Debug;
+
+public class ExpressionContext {
+
+ //########################################################################
+ // Private Fields
+
+ private final Environment environment;
+ private final Map functions;
+ private final Map variables;
+ private final Symbol owner;
+
+ private int current;
+ private int maximum;
+
+ //########################################################################
+ // Public Constructors
+
+ public ExpressionContext(Environment environment, Symbol owner) {
+ this.environment = environment;
+ this.functions = new HashMap();
+ this.variables = new HashMap();
+ this.owner = owner;
+ this.current = 0;
+ this.maximum = 0;
+ }
+
+ //########################################################################
+ // Public Methods - insert
+
+ public Function insertLabel(Symbol symbol) {
+ Function function = Function.Label(symbol);
+ assert Debug.log("insert label ", Debug.show(symbol));
+ assert !functions.containsKey(symbol) : Debug.show(symbol);
+ functions.put(symbol, function);
+ return function;
+ }
+
+ public Variable insertVariable(Symbol symbol, Variable variable) {
+ assert Debug.log("insert variable", Debug.show(symbol));
+ assert !variables.containsKey(symbol) : Debug.show(symbol);
+ variables.put(symbol, variable);
+ return variable;
+ }
+
+ //########################################################################
+ // Public Methods - lookup
+
+ public Template lookupTemplate(Symbol symbol) {
+ return environment.lookupTemplate(symbol);
+ }
+
+ public Function lookupFunction(Symbol symbol) {
+ Object value = functions.get(symbol);
+ if (value != null) return (Function)value;
+ return environment.lookupFunction(symbol);
+ }
+
+ public Variable lookupVariable(Symbol symbol) {
+ Object value = variables.get(symbol);
+ if (value != null) return (Variable)value;
+ return environment.lookupVariable(symbol);
+ }
+
+ //########################################################################
+ // Public Methods - owner
+
+ public Symbol owner() {
+ return owner;
+ }
+
+ //########################################################################
+ // Public Methods - stack
+
+ public void stacksize(int size) {
+ assert size >= 0 : size;
+ maximum = Math.max(current, maximum);
+ current = size;
+ }
+
+ public int stacksize() {
+ return current;
+ }
+
+ public int stackmax() {
+ return maximum = Math.max(current, maximum);
+ }
+
+ public int push() {
+ return current++;
+ }
+
+ public int pop() {
+ maximum = Math.max(current, maximum);
+ return --current;
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/Function.java b/sources/scala/tools/scalai/Function.java
new file mode 100644
index 0000000000..3809c0faff
--- /dev/null
+++ b/sources/scala/tools/scalai/Function.java
@@ -0,0 +1,90 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Function.java,v 1.5 2002/07/01 13:16:39 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+
+import scalac.symtab.Symbol;
+import scalac.util.Debug;
+
+public class Function {
+
+ //########################################################################
+ // Public Cases
+
+ public case Global(CodePromise code);
+ public case Member(Symbol symbol);
+ public case Label(Symbol symbol);
+
+ public case JavaConstructor(Constructor constructor);
+ public case JavaMethod(Method method);
+
+ public case Pos;
+ public case Neg;
+ public case Throw;
+ public case StringPlus;
+ public case EqEq;
+ public case BangEq;
+ public case HashCode;
+ public case ToString;
+
+ //########################################################################
+ // Public Methods
+
+ public String toString() {
+ switch (this) {
+
+ case Global(CodePromise code):
+ return "Global(" + code + ")";
+
+ case Member(Symbol symbol):
+ return "Member(" + Debug.show(symbol) + ")";
+
+ case Label(Symbol symbol):
+ return "Label(" + Debug.show(symbol) + ")";
+
+ case JavaMethod(Method method):
+ return "JavaMethod(" + method + ")";
+
+ case JavaConstructor(Constructor constructor):
+ return "JavaConstructor(" + constructor + ")";
+
+ case Pos:
+ return "Pos";
+
+ case Neg:
+ return "Neg";
+
+ case Throw:
+ return "Throw";
+
+ case StringPlus:
+ return "StringPlus";
+
+ case EqEq:
+ return "EqEq";
+
+ case BangEq:
+ return "BangEq";
+
+ case HashCode:
+ return "HashCode";
+
+ case ToString:
+ return "ToString";
+
+ default:
+ throw Debug.abort("illegal function", this);
+ }
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/Interpreter.java b/sources/scala/tools/scalai/Interpreter.java
new file mode 100644
index 0000000000..373e7e2ea0
--- /dev/null
+++ b/sources/scala/tools/scalai/Interpreter.java
@@ -0,0 +1,444 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Interpreter.java,v 1.63 2002/09/13 01:50:30 paltherr Exp $
+// $Id$
+
+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 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), "<files>",
+ "Load files (or repeat last use if no files are given)");
+ matcher.insert(":use", new Integer(USE), "<files>",
+ "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;
+ }
+
+ //########################################################################
+ // 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();
+ this.evaluator = new Evaluator();
+ this.compiler = new Compiler(global,evaluator,new SymbolWriter(writer)); // !!!
+ 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);
+ // Compute something to start compiler and force loading of Predef
+ if (interactive && program.length == 0 && main == null) eval("null");
+ 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[] files) {
+ if (files.length == 0) return true;
+ global.compile(files, false);
+ return interpret(false);
+ }
+
+ public boolean call(String main, String[] args) {
+ new EntryPointCompiler(PRODUCT, global).compile(main, args);
+ return interpret(false);
+ }
+
+ public boolean interpret(boolean interactive) {
+ if (global.reporter.errors() == 0) {
+ CodeContainer code = compiler.compile(global.units, interactive);
+ EvaluatorResult result;
+ try {
+ result = EvaluatorResult.Value(evaluator.evaluate(code));
+ } catch (EvaluatorException exception) {
+ result = EvaluatorResult.Error(exception);
+ }
+ show(result, interactive);
+ }
+ Sourcefile.flushSources();
+ return true;
+ }
+
+ public void show(EvaluatorResult result, boolean interactive) {
+ switch (result) {
+ case Void:
+ return;
+ case Value(Object value):
+ // !!! if (value != null)
+ if (interactive && value != null) writer.println(value);
+ return;
+ case Error(EvaluatorException exception):
+ writer.println(exception.mkString(global));
+ 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);
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/InterpreterCommand.java b/sources/scala/tools/scalai/InterpreterCommand.java
new file mode 100644
index 0000000000..46704311e0
--- /dev/null
+++ b/sources/scala/tools/scalai/InterpreterCommand.java
@@ -0,0 +1,62 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: InterpreterCommand.java,v 1.3 2002/09/02 12:58:22 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import scalac.PhaseRepository;
+import scalac.CompilerCommand;
+import scalac.util.Reporter;
+import scalac.util.BooleanOptionParser;
+import scalac.util.ScalaProgramArgumentParser;
+
+public class InterpreterCommand extends CompilerCommand {
+
+ //########################################################################
+ // Public Fields
+
+ public final BooleanOptionParser interactive;
+ public final BooleanOptionParser emacs;
+ public final ScalaProgramArgumentParser program;
+
+ //########################################################################
+ // Public Constructors
+
+ public InterpreterCommand(String product, String version,
+ Reporter reporter, PhaseRepository phases)
+ {
+ this(product, version, "<source files> [-- <module> <args>]",
+ reporter, phases);
+ }
+
+ public InterpreterCommand(String product, String version, String syntax,
+ Reporter reporter, PhaseRepository phases)
+ {
+ super(product, version, syntax, reporter, phases);
+
+ this.interactive = new BooleanOptionParser(this,
+ "interactive", "Start interpreter in interactive mode",
+ false);
+
+ this.emacs = new BooleanOptionParser(this,
+ "emacs", "Use Emacs editing mode",
+ false);
+
+ this.program = new ScalaProgramArgumentParser(this);
+
+ remove(outpath);
+ remove(target);
+ remove(jaco);
+
+ add(0, interactive);
+ add(1, emacs);
+ add(parsers().indexOf(unknown_options), program);
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/JavaMirror.java b/sources/scala/tools/scalai/JavaMirror.java
new file mode 100644
index 0000000000..b84a18dd36
--- /dev/null
+++ b/sources/scala/tools/scalai/JavaMirror.java
@@ -0,0 +1,245 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: JavaMirror.java,v 1.8 2002/10/01 16:14:07 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+import java.util.Map;
+import java.util.HashMap;
+
+import scalac.symtab.TypeTags;
+import scalac.symtab.Type;
+import scalac.symtab.Symbol;
+import scalac.symtab.Definitions;
+import scalac.util.Debug;
+
+public class JavaMirror {
+
+ //########################################################################
+ // Private Constants
+
+ private static final Class void_class = Void.TYPE;
+ private static final Class boolean_class = Boolean.TYPE;
+ private static final Class byte_class = Byte.TYPE;
+ private static final Class short_class = Short.TYPE;
+ private static final Class char_class = Character.TYPE;
+ private static final Class int_class = Integer.TYPE;
+ private static final Class long_class = Long.TYPE;
+ private static final Class float_class = Float.TYPE;
+ private static final Class double_class = Double.TYPE;
+ private static final Class Object_class = Object.class;
+
+ //########################################################################
+ // Private Fields
+
+ private final ClassLoader loader;
+
+ private final Map/*<Class ,Class >*/ arrays;
+ private final Map/*<Symbol,Class >*/ classes;
+ private final Map/*<Symbol,Field >*/ fields;
+ private final Map/*<Symbol,Method >*/ methods;
+ private final Map/*<Symbol,Constructor>*/ constructors;
+
+ //########################################################################
+ // Public Constructors
+
+ public JavaMirror(Definitions definitions, ClassLoader loader) {
+ this.loader = loader;
+ this.arrays = new HashMap();
+ this.classes = new HashMap();
+ this.fields = new HashMap();
+ this.methods = new HashMap();
+ this.constructors = new HashMap();
+ this.classes.put(definitions.ANY_CLASS, Object_class);
+ this.classes.put(definitions.ANYREF_CLASS, Object_class);
+ }
+
+ //########################################################################
+ // Public Methods - arrays
+
+ public Class getArray(Class component) {
+ Object value = arrays.get(component);
+ if (value != null) return (Class)value;
+ Class array = getArray0(component);
+ arrays.put(component, array);
+ return array;
+ }
+
+ private Class getArray0(Class component) {
+ String classname = "[" + getArrayComponentName(component);
+ try {
+ return Class.forName(classname, false, loader);
+ } catch (ClassNotFoundException exception) {
+ throw Debug.abort("no such class", classname);
+ }
+ }
+
+ private String getArrayComponentName(Class component) {
+ if (component.isPrimitive()) {
+ if (component == boolean_class) return "Z";
+ if (component == byte_class) return "B";
+ if (component == short_class) return "S";
+ if (component == char_class) return "C";
+ if (component == int_class) return "I";
+ if (component == long_class) return "J";
+ if (component == float_class) return "F";
+ if (component == double_class) return "D";
+ throw Debug.abort("unknown primitive class", component);
+ }
+ String classname = component.getName();
+ return component.isArray() ? classname : "L" + classname + ";";
+ }
+
+ //########################################################################
+ // Public Methods - classes
+
+ public Class getClass(Type type) {
+ switch (type) {
+
+ case UnboxedType(int kind):
+ return getClass(kind);
+
+ case UnboxedArrayType(Type component):
+ return getArray(getClass(component));
+
+ case TypeRef(_, Symbol symbol, _):
+ return getClass(symbol);
+
+ default:
+ throw Debug.abort("illegal type", type);
+ }
+ }
+
+ public Class getClass(int kind) {
+ switch (kind) {
+ case TypeTags.UNIT : return void_class;
+ case TypeTags.BOOLEAN: return boolean_class;
+ case TypeTags.BYTE : return byte_class;
+ case TypeTags.SHORT : return short_class;
+ case TypeTags.CHAR : return char_class;
+ case TypeTags.INT : return int_class;
+ case TypeTags.LONG : return long_class;
+ case TypeTags.FLOAT : return float_class;
+ case TypeTags.DOUBLE : return double_class;
+ default : throw Debug.abort("kind = " + kind);
+ }
+ }
+
+ public Class getClass(Symbol symbol) {
+ Object value = classes.get(symbol);
+ if (value != null) return (Class)value;
+ Class mirror = getClass0(symbol);
+ assert Debug.log("java mirror", Debug.show(symbol) + " -> " + mirror);
+ classes.put(symbol, mirror);
+ return mirror;
+ }
+
+ private Class getClass0(Symbol symbol) {
+ try {
+ return Class.forName(symbol.fullName().toString(), false, loader);
+ } catch (ClassNotFoundException exception) {
+ throw Debug.abort("no such class", symbol);
+ }
+ }
+
+ //########################################################################
+ // Public Methods - fields
+
+ public Field getField(Symbol symbol) {
+ Object value = fields.get(symbol);
+ if (value != null) return (Field)value;
+ Field mirror = getField0(symbol);
+ assert Debug.log("java mirror", Debug.show(symbol) + " -> " + mirror);
+ fields.put(symbol, mirror);
+ return mirror;
+ }
+
+ private Field getField0(Symbol symbol) {
+ Class owner = getClass(symbol.owner());
+ try {
+ return owner.getField(symbol.name.toString());
+ } catch (NoSuchFieldException exception) {
+ throw Debug.abort("no such field", symbol);
+ }
+ }
+
+ //########################################################################
+ // Public Methods - methods
+
+ public Method getMethod(Symbol symbol) {
+ Object value = methods.get(symbol);
+ if (value != null) return (Method)value;
+ Method mirror = getMethod0(symbol);
+ assert Debug.log("java mirror", Debug.show(symbol) + " -> " + mirror);
+ methods.put(symbol, mirror);
+ return mirror;
+ }
+
+ private Method getMethod0(Symbol symbol) {
+ Class owner = getClass(symbol.owner());
+ Class[] params = getVParamsOf(symbol.type());
+ try {
+ return owner.getMethod(symbol.name.toString(), params);
+ } catch (NoSuchMethodException exception) {
+ throw Debug.abort("no such method", symbol);
+ }
+ }
+
+ //########################################################################
+ // Public Methods - constructors
+
+ public Constructor getConstructor(Symbol symbol) {
+ Object value = constructors.get(symbol);
+ if (value != null) return (Constructor)value;
+ Constructor mirror = getConstructor0(symbol);
+ assert Debug.log("java mirror", Debug.show(symbol) + " -> " + mirror);
+ constructors.put(symbol, mirror);
+ return mirror;
+ }
+
+ private Constructor getConstructor0(Symbol symbol) {
+ Class owner = getClass(symbol.owner());
+ Class[] params = getVParamsOf(symbol.type());
+ try {
+ return owner.getConstructor(params);
+ } catch (NoSuchMethodException exception) {
+ throw Debug.abort("no such constructor", symbol);
+ }
+ }
+
+ //########################################################################
+ // Public Methods - value parameters
+
+ public Class[] getVParamsOf(Symbol symbol) {
+ return getVParamsOf(symbol.type());
+ }
+
+ public Class[] getVParamsOf(Type type) {
+ switch (type) {
+
+ case MethodType(Symbol[] vparams, _):
+ return getVParams(vparams);
+
+ default:
+ throw Debug.abort("illegal type", type);
+ }
+ }
+
+ public Class[] getVParams(Symbol[] symbols) {
+ Class[] vparams = new Class[symbols.length];
+ for (int i = 0; i < vparams.length; i++) {
+ vparams[i] = getClass(symbols[i].type());
+ }
+ return vparams;
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/Main.java b/sources/scala/tools/scalai/Main.java
new file mode 100644
index 0000000000..ebfea5beaf
--- /dev/null
+++ b/sources/scala/tools/scalai/Main.java
@@ -0,0 +1,41 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Main.java,v 1.2 2002/08/30 15:44:55 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import scalac.PhaseRepository;
+import scalac.util.Reporter;
+
+public class Main {
+
+ //########################################################################
+ // Public Constants
+
+ public static final String PRODUCT =
+ System.getProperty("scala.product", "scala");
+ public static final String VERSION =
+ System.getProperty("scala.version", "1.0");
+
+ //########################################################################
+ // Public Methods
+
+ public static void main(String[] args) {
+ Reporter reporter = new Reporter();
+ InterpreterCommand command = new InterpreterCommand(
+ PRODUCT, VERSION, reporter, new PhaseRepository());
+ if (command.parse(args)) {
+ Interpreter interpreter = new Interpreter(command);
+ interpreter.main(command.files.toArray(),
+ command.program.main, command.program.args);
+ }
+ System.exit((reporter.errors() > 0) ? -1 : 0);
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/Override.java b/sources/scala/tools/scalai/Override.java
new file mode 100644
index 0000000000..d2f5a5e69d
--- /dev/null
+++ b/sources/scala/tools/scalai/Override.java
@@ -0,0 +1,60 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Override.java,v 1.2 2002/07/11 09:20:41 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.lang.reflect.Method;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import scalac.symtab.Symbol;
+
+public class Override {
+
+ //########################################################################
+ // Private Fields
+
+ private final Set/*<Method|Symbol>*/ methods;
+
+ //########################################################################
+ // Public Constructors
+
+ private Override() {
+ this.methods = new HashSet();
+ }
+
+ //########################################################################
+ // Public Methods
+
+ public static Override empty() {
+ return new Override();
+ }
+
+ public Override insert(Method method) {
+ methods.add(method);
+ return this;
+ }
+
+ public Override insert(Symbol symbol) {
+ methods.add(symbol);
+ return this;
+ }
+
+ public Override insert(Override override) {
+ methods.addAll(override.methods);
+ return this;
+ }
+
+ public Iterator iterator() {
+ return methods.iterator();
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/PathClassLoader.java b/sources/scala/tools/scalai/PathClassLoader.java
new file mode 100644
index 0000000000..ca5f195fef
--- /dev/null
+++ b/sources/scala/tools/scalai/PathClassLoader.java
@@ -0,0 +1,46 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: PathClassLoader.java,v 1.1 2002/10/01 16:09:34 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.io.IOException;
+
+import scalac.util.ClassPath;
+import scalac.util.AbstractFile;
+
+public class PathClassLoader extends ClassLoader {
+
+ //########################################################################
+ // PathClassLoader state
+
+ private final ClassPath classpath;
+
+ //########################################################################
+ // PathClassLoader constructors
+
+ public PathClassLoader(ClassPath classpath) {
+ this.classpath = classpath;
+ }
+
+ //########################################################################
+ // ClassLoader interface
+
+ public Class findClass(String name) throws ClassNotFoundException {
+ try {
+ String filename = name.replace('.', '/') + ".class";
+ AbstractFile file = classpath.openFile(filename);
+ byte[] bytes = file.read();
+ return defineClass(name, bytes, 0, bytes.length);
+ } catch (IOException exception) {
+ throw new ClassNotFoundException(name);
+ }
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/ScalaFunction.java b/sources/scala/tools/scalai/ScalaFunction.java
new file mode 100644
index 0000000000..7789609c76
--- /dev/null
+++ b/sources/scala/tools/scalai/ScalaFunction.java
@@ -0,0 +1,53 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: ScalaFunction.java,v 1.9 2002/07/03 16:08:00 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import scalac.ast.Tree;
+import scalac.ast.Tree.ValDef;
+import scalac.symtab.Symbol;
+import scalac.util.Debug;
+
+public class ScalaFunction extends CodeGenerator {
+
+ //########################################################################
+ // Private Fields
+
+ private final Compiler compiler;
+ private final Symbol symbol;
+ private final ValDef[] params;
+ private final Tree body;
+
+ //########################################################################
+ // Public Constructors
+
+ public ScalaFunction(Compiler compiler, Symbol symbol, ValDef[] params, Tree body) {
+ this.compiler = compiler;
+ this.symbol = symbol;
+ this.params = params;
+ this.body = body;
+ }
+
+ //########################################################################
+ // Public Methods - CodeGenerator interface
+
+ public CodeContainer generate() {
+ return compiler.compile(symbol, body, params);
+ }
+
+ //########################################################################
+ // Public Methods - Object interface
+
+ // !!!
+ public String toString() {
+ return "ScalaFunction(" + Debug.show(symbol) + ")";
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/ScalaObject.java b/sources/scala/tools/scalai/ScalaObject.java
new file mode 100644
index 0000000000..0d9f65c7c9
--- /dev/null
+++ b/sources/scala/tools/scalai/ScalaObject.java
@@ -0,0 +1,60 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: ScalaObject.java,v 1.7 2002/07/11 11:46:53 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.InvocationHandler;
+
+import scalac.symtab.Symbol;
+
+public class ScalaObject implements InvocationHandler {
+
+ //########################################################################
+ // Public Fields
+
+ public final ScalaTemplate template;
+ public final Object[] variables;
+
+ //########################################################################
+ // Public Constructors
+
+ public ScalaObject(ScalaTemplate template, Object[] variables) {
+ this.template = template;
+ this.variables = variables;
+ }
+
+ //########################################################################
+ // Public Methods - ScalaObject interface
+
+ public Object invoke(Object self, Symbol symbol, Object[] args) {
+ return template.invoke(self, symbol, args);
+ }
+
+ //########################################################################
+ // Public Methods - InvocationHandler interface
+
+ public Object invoke(Object self, Method method, Object[] args) {
+ return template.invoke(self, method, args);
+ }
+
+ //########################################################################
+ // Public Methods - Object interface
+
+ public boolean equals(Object that) {
+ return that instanceof Proxy && Proxy.getInvocationHandler(that)==this;
+ }
+
+ public String toString() {
+ return template.getName() + "@" + Integer.toHexString(hashCode());
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/ScalaTemplate.java b/sources/scala/tools/scalai/ScalaTemplate.java
new file mode 100644
index 0000000000..57aaf793e9
--- /dev/null
+++ b/sources/scala/tools/scalai/ScalaTemplate.java
@@ -0,0 +1,99 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: ScalaTemplate.java,v 1.8 2002/07/11 11:46:53 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+
+import scalac.util.Name;
+import scalac.symtab.Symbol;
+import scalac.util.Debug;
+
+public class ScalaTemplate {
+
+ //########################################################################
+ // Private Fields
+
+ private final Evaluator evaluator;
+ private final Symbol symbol;
+ private final Function constructor;
+ private final Map/*<Method|Symbol,XYScalaFunction>*/ vtable;
+ private final Object[] fields;
+
+ //########################################################################
+ // Public Constructors
+
+ public ScalaTemplate(Evaluator evaluator, Symbol symbol, Function constructor, Map vtable, Object[] fields) {
+ this.evaluator = evaluator;
+ this.symbol = symbol;
+ this.constructor = constructor;
+ this.vtable = vtable;
+ this.fields = fields;
+ }
+
+ //########################################################################
+ // Public Methods - ScalaTemplate interface
+
+ public Name getName() {
+ return symbol.fullName();
+ }
+
+ public Symbol getSymbol() {
+ return symbol;
+ }
+
+ public Function getConstructor() {
+ return constructor;
+ }
+
+ public Map getMethods() {
+ return new HashMap(vtable);
+ }
+
+ public List getFields() {
+ List list = new ArrayList(fields.length);
+ for (int i = 0; i < fields.length; i++) list.add(fields[i]);
+ return list;
+ }
+
+ public CodePromise getMethod(Symbol symbol) {
+ return (CodePromise)vtable.get(symbol);
+ }
+
+ public ScalaObject getHandler() {
+ Object[] fields = new Object[this.fields.length];
+ System.arraycopy(this.fields, 0, fields, 0, fields.length);
+ return new ScalaObject(this, fields);
+ }
+
+ public Object invoke(Object self, Symbol method, Object[] args) {
+ CodePromise code = (CodePromise)vtable.get(method);
+ assert code != null : Debug.show(symbol) + "->" + Debug.show(method);
+ return evaluator.evaluate(code, self, args);
+ }
+
+ public Object invoke(Object self, Method method, Object[] args) {
+ CodePromise code = (CodePromise)vtable.get(method);
+ assert code != null : Debug.show(symbol) + "->" + Debug.show(method);
+ return evaluator.evaluate(code, self, args);
+ }
+
+ //########################################################################
+ // Public Methods - Object interface
+
+ public String toString() {
+ return "template " + getName();
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/SymbolWriter.java b/sources/scala/tools/scalai/SymbolWriter.java
new file mode 100644
index 0000000000..3839582c55
--- /dev/null
+++ b/sources/scala/tools/scalai/SymbolWriter.java
@@ -0,0 +1,42 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: SymbolWriter.java,v 1.1 2002/07/12 16:59:14 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.io.PrintWriter;
+
+import scalac.symtab.Symbol;
+
+public class SymbolWriter {
+
+ //########################################################################
+ // Private Fields
+
+ public final PrintWriter writer;
+
+ //########################################################################
+ // Public Constructors
+
+ public SymbolWriter(PrintWriter writer) {
+ this.writer = writer;
+ }
+
+ //########################################################################
+ // Public Methods
+
+ public void write1(Symbol symbol) {
+ writer.println(symbol.defString());
+ }
+
+ public void write2(Symbol symbol, Object value) {
+ writer.println(symbol.defString() + " = " + value);
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/Template.java b/sources/scala/tools/scalai/Template.java
new file mode 100644
index 0000000000..ea3cc9dc4e
--- /dev/null
+++ b/sources/scala/tools/scalai/Template.java
@@ -0,0 +1,40 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Template.java,v 1.2 2002/06/28 17:23:59 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import scalac.util.Debug;
+
+public class Template {
+
+ //########################################################################
+ // Public Cases
+
+ public case Global(ScalaTemplate template);
+ public case JavaClass(Class clasz);
+
+ //########################################################################
+ // Public Methods
+
+ public String toString() {
+ switch (this) {
+
+ case Global(ScalaTemplate template):
+ return "Global(" + template + ")";
+
+ case JavaClass(Class clasz):
+ return "JavaClass(" + clasz + ")";
+
+ default:
+ throw Debug.abort("unknown case", this);
+ }
+ }
+
+ //########################################################################
+}
diff --git a/sources/scala/tools/scalai/Variable.java b/sources/scala/tools/scalai/Variable.java
new file mode 100644
index 0000000000..42e2c4d4b5
--- /dev/null
+++ b/sources/scala/tools/scalai/Variable.java
@@ -0,0 +1,59 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: Variable.java,v 1.4 2002/06/17 12:33:38 paltherr Exp $
+// $Id$
+
+package scalai;
+
+import java.lang.reflect.Field;
+
+import scalac.util.Debug;
+
+public class Variable {
+
+ //########################################################################
+ // Public Cases
+
+ // !!! Object/Field(int index)
+ // !!! Frame/Local(int index)
+ // !!! Stack(int index)
+ // !!! Java(Field field)
+
+ public case Global(Object value);
+ public case Module(CodePromise body, Object value);
+ public case Context(int level, int index);
+ public case Member(int index);
+ public case JavaField(Field field);
+
+ //########################################################################
+ // Public Methods
+
+ public String toString() {
+ switch (this) {
+
+ case Global(Object value):
+ return "Global(" + Debug.show(value) + ")";
+
+ case Module(CodePromise body, Object value):
+ return "Module(" + body + "," + Debug.show(value) + ")";
+
+ case Context(int level, int index):
+ return "Context(" + level + "," + index + ")";
+
+ case Member(int index):
+ return "Member(" + index + ")";
+
+ case JavaField(Field field):
+ return "Java(" + field + ")";
+
+ default:
+ throw Debug.abort("illegal variable", this);
+ }
+ }
+
+ //########################################################################
+}