[e-cvs] cvs commit: e/src/jsrc/org/erights/e/ui/elmer EInterpAdapter.java
markm@eros.cs.jhu.edu
markm@eros.cs.jhu.edu
Sun, 5 Aug 2001 03:01:25 -0400
markm 01/08/05 03:01:25
Modified: src Makefile
src/csrc/setup e-template.txt
src/esrc/org/erights/e/install/win32
installToRegistry.emaker
src/jsrc/org/erights/e/elang/interp Interp.java
Interpreter.java ScopeSetup.java
src/jsrc/org/erights/e/ui/elmer EInterpAdapter.java
Added: src/jsrc/org/erights/e/elang/interp InteractiveInterp.java
InterpLoop.java
Log:
split Interp into interactive and non-interactive variants
Revision Changes Path
1.100 +3 -3 e/src/Makefile
Index: Makefile
===================================================================
RCS file: /cvs/e/src/Makefile,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -r1.99 -r1.100
--- Makefile 2001/05/10 03:19:21 1.99
+++ Makefile 2001/08/05 07:01:24 1.100
@@ -6,9 +6,9 @@
default: draft explain
# Prefix tagging this release's attributes
-PREFIX=stl-E
-DOTVER=0.8.9v
-TAGVER=0_8_9v
+PREFIX=tl-E
+DOTVER=0.8.9w
+TAGVER=0_8_9w
RELEASE=working
TOP=..
1.7 +16 -13 e/src/csrc/setup/e-template.txt
Index: e-template.txt
===================================================================
RCS file: /cvs/e/src/csrc/setup/e-template.txt,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- e-template.txt 2001/03/31 06:47:32 1.6
+++ e-template.txt 2001/08/05 07:01:24 1.7
@@ -98,14 +98,14 @@
while [ $(($# >= 1)) = 1 ]; do
case $1 in
- -cp ) jpush "$1"; shift
- if [ $(($# < 1)) = 1 ]; then usage; fi
- jpush "$1"; shift;;
- -D* ) jpush "$1"; shift;;
- -J* ) jpush "${1#-J}"; shift;;
+ -cp ) jpush "$1"; shift
+ if [ $(($# < 1)) = 1 ]; then usage; fi
+ jpush "$1"; shift;;
+ -D* ) jpush "$1"; shift;;
+ -J* ) jpush "${1#-J}"; shift;;
--help )
- echo "e [-options] [(e-script.e | \"-\") [args...]]"
- echo "where options include:"
+ echo "e [-options] script [args...]"
+ echo "where options are:"
echo " -cp <classpath> Defines classpath. Passed to java."
echo " -D<name>=<value> Defines Property. Passed to java."
echo " -J<java-option> java-option passed to java."
@@ -113,14 +113,17 @@
echo " --help Prints this out and exits."
echo " --show Shows the java command line, rather"
echo " than executing it"
- echo "If \"-\" is used instead of a script file name,"
- echo "then E commands are read from stdin."
+ echo "and script is one of"
+ echo " filename.e The E script file to execute"
+ echo " - Use stdin as script file"
+ echo " --interact An interactive command line"
exit 0;;
- --show) execflag=show; shift;;
- -) break;;
- -*) usage;;
+ --show) execflag=show; shift;;
+ -) break;;
+ --interact) break;;
+ -*) usage;;
*)
- ecmd[0]=`normalizeEPath "$1"`; shift
+ ecmd[0]=`normalizeEPath "$1"`; shift
break;;
esac
done
1.8 +1 -1 e/src/esrc/org/erights/e/install/win32/installToRegistry.emaker
Index: installToRegistry.emaker
===================================================================
RCS file: /cvs/e/src/esrc/org/erights/e/install/win32/installToRegistry.emaker,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- installToRegistry.emaker 2001/04/05 01:21:59 1.7
+++ installToRegistry.emaker 2001/08/05 07:01:24 1.8
@@ -35,7 +35,7 @@
def addCommand := addCommandMaker(addCommandCmd)
## Shortcut to E
- makeShortcut(ecmd,
+ makeShortcut(ecmd + ["--interact"],
`$ehome/bin/shortcuts/e.lnk`,
launchDir,
`$ehome/bin/icons/e-lambda.ico`,
1.59 +52 -146 e/src/jsrc/org/erights/e/elang/interp/Interp.java
Index: Interp.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/interp/Interp.java,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -r1.58 -r1.59
--- Interp.java 2001/08/04 06:56:52 1.58
+++ Interp.java 2001/08/05 07:01:24 1.59
@@ -58,27 +58,13 @@
/**
- * The E read-eval-print interpreter loop.
+ * The main, non-interactive, E read-eval interpreter loop.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
-public class Interp implements Interpreter {
+public class Interp implements Interpreter, InterpLoop {
static boolean uiInititialized = false;
-
- static EExpr[] SubstArgs = null;
-
- static private void initSubst() {
- if (null != SubstArgs) {
- return;
- }
- EExpr[] sargs = new EExpr[10];
- for (int i = 0; i < sargs.length; i++) {
- Twine twine = Twine.fromString("interp getResult(" + i + ")");
- sargs[i] = (EExpr)EParser.run(twine);
- }
- SubstArgs = sargs;
- }
private ConstList myArgs;
private ConstMap myProps;
@@ -89,8 +75,6 @@
private EParser myParser;
private Scope[] myTopPov;
- private boolean myInteractiveFlag = false;
- private boolean myExpandFlag = false;
private boolean myVerboseFlag = false;
private Object myTopLock = new Object();
@@ -98,14 +82,10 @@
private boolean myShouldExit = false;
private Throwable myOptProblem = null;
- private Object[] myResults = new Object[10];
-
/**
* Must call setState() to initialize. This allows subclassing.
*/
- /*package*/ Interp() {
- initSubst();
- }
+ /*package*/ Interp() {}
/**
*
@@ -119,8 +99,6 @@
EParser parser,
Scope[] topPov,
- boolean interactiveFlag,
- boolean expandFlag,
boolean verboseFlag)
{
myArgs = args;
@@ -132,8 +110,6 @@
myParser = parser;
myTopPov = topPov;
- myInteractiveFlag = interactiveFlag;
- myExpandFlag = expandFlag;
myVerboseFlag = verboseFlag;
}
@@ -148,14 +124,14 @@
*
*/
public boolean getExpand() {
- return myExpandFlag;
+ return false;
}
/**
*
*/
public boolean getInteractive() {
- return myInteractiveFlag;
+ return false;
}
/**
@@ -178,21 +154,11 @@
public boolean getVerbose() {
return myVerboseFlag;
}
-
- /**
- *
- */
- public Object getResult(int i) {
- return myResults[i];
- }
/**
*
*/
public void gc() {
- for (int i = 0; i < myResults.length; i++) {
- myResults[i] = null;
- }
System.gc();
}
@@ -200,7 +166,8 @@
*
*/
public void setExpand(boolean flag) {
- myExpandFlag = flag;
+ throw new RuntimeException
+ ("can't setExpand in a non-interactive interpreter");
}
/**
@@ -243,26 +210,19 @@
/**
* Creates an E interpreter.
*
- * @param args; the command line arguments. If 'optLineFeeder' is null,
- * the information
- * necessary to construct it are first extracted from args, and
- * only the remaining args are stored.
- *
- * @param props A ConstMap thought to reflect System.getProperties
- *
- * @param outs; where normal output should go
- * @param errs; where diagnostic output should go (may be the same
- * as 'outs')
- *
- * @param optLineFeeder nullOk; if null, derived by extracting the first
- * argument of args as the name of a file to interpret.
- *
- * @param optTopScope nullOk; if null, the standard initial scope is
- * constructed.
- *
- * @param partialFlag What to do on end of file. If false, throws
- * SyntaxException. If true (meaning a partial parse is ok), throws
- * NeedMoreException.
+ * @param args The command line arguments. If 'optLineFeeder' is null,
+ * the information necessary to construct it are first
+ * extracted from args, and only the remaining args are
+ * stored.
+ * @param props A ConstMap thought to reflect System.getProperties()
+ *
+ * @param outs Where normal output should go
+ * @param errs Where diagnostic output should go (may be the same
+ * as 'outs')
+ * @param optLineFeeder If null, derived by extracting the first
+ * argument of args as the name of a file to
+ * interpret.
+ * @param optTopScope If null, the standard initial scope is constructed.
*/
static public Interp make(ConstList args,
ConstMap props,
@@ -271,11 +231,9 @@
Runner runner,
LineFeeder optLineFeeder,
- Scope optTopScope,
- boolean partialFlag)
+ Scope optTopScope)
throws IOException, AlreadyDefinedException {
String fname = "";
- boolean interactiveFlag;
if (optLineFeeder == null) {
// [options...] [ (fname | "" | -) args...]
// options ::= //nothing yet..
@@ -293,41 +251,32 @@
}
}
- interactiveFlag = fname.equals("") ||
- testProp(props, "e.interp.interactive");
BufferedReader ins;
- if (fname.equals("") || fname.equals("-")) {
- //don't buffer the interactive or piped case
+ if (fname.equals("")) {
+ throw new RuntimeException
+ ("Missing file name. Use '-' for stdin");
+ } else if (fname.equals("-")) {
+ //don't buffer the piped case
ins = PrintStreamWriter.in();
} else {
File src = FileGetter.get(fname);
ins = new BufferedReader(new FileReader(src));
}
- TextWriter optOut = null;
- if (interactiveFlag) {
- optOut = outs;
- }
- optLineFeeder = new FileFeeder(fname, ins, optOut, null);
- } else {
- interactiveFlag = testProp(props, "e.interp.interactive");
+ optLineFeeder = new FileFeeder(fname, ins, null, null);
}
ELexer lexer = new ELexer(optLineFeeder,
- partialFlag,
+ false,
testProp(props, "e.enable.notabs"));
EParser parser = new EParser(props,
lexer,
testProp(props, "e.interp.parseSpam"),
true);
- if (optLineFeeder instanceof FileFeeder) {
- ((FileFeeder)optLineFeeder).setParser(parser);
- }
-
Object[] promise = Ref.promise();
Ref interpPromise = (Ref)promise[0];
Resolver interpResolver = (Resolver)promise[1];
if (optTopScope == null) {
- optTopScope = ScopeSetup.privileged(interactiveFlag,
+ optTopScope = ScopeSetup.privileged(false,
outs,
errs,
props,
@@ -335,7 +284,6 @@
}
Scope[] topPov = optTopScope.newPov();
- boolean expandFlag = testProp(props, "e.interp.expand");
boolean verboseFlag = testProp(props, "e.interp.verbose");
Interp result = new Interp();
@@ -348,8 +296,6 @@
parser,
topPov,
- interactiveFlag,
- expandFlag,
verboseFlag);
interpResolver.resolve(result);
return result;
@@ -454,67 +400,29 @@
}
/**
- *
- */
- private void pushResult(Object result) {
- System.arraycopy(myResults, 0, myResults, 1, 9);
- myResults[0] = result;
- }
-
- /**
* Called while the vatLock is held.
*
* @see org.erights.e.elib.prim.Runner#callNow
*/
public void evalPrint(EExpr eExpr) {
- try {
- if (myExpandFlag) {
- myOuts.print("# expansion: ");
- eExpr.lnPrintOn(myOuts.indent("# "));
- myOuts.println();
- myOuts.println();
- }
-
- Object result = null;
- try {
- result = Ref.resolution(eExpr.eval(myTopPov));
- pushResult(result);
- } catch (Throwable t) {
- result = Ref.broken(t);
- pushResult(result);
- throw t;
- }
-
- if (myInteractiveFlag) {
- if (result != null) {
- commentBlock(myOuts, "value").quote(result);
- myOuts.println();
- myOuts.println();
- }
- myOuts.flush();
- myErrs.flush();
- }
- } catch (Throwable t) {
- throw ExceptionMgr.asSafe(t);
- }
+ myShouldBlock = false;
+ myShouldExit = false;
+ myOptProblem = null;
+
+ eExpr.eval(myTopPov);
}
/**
*
*/
- private void interpretOne() throws NeedMoreException {
+ private void interpretOne() {
try {
EExpr optExpr = (EExpr)myParser.optParse();
if (null != optExpr) {
- optExpr = optExpr.substitute(SubstArgs);
Object[] args = { optExpr };
myRunner.callNow(this, "evalPrint", args);
}
} catch (Throwable t) {
- Throwable leaf = ThrowableSugar.leaf(t);
- if (leaf instanceof NeedMoreException) {
- throw (NeedMoreException)leaf;
- }
reportProblem(t);
throw ExceptionMgr.asSafe(t);
@@ -542,8 +450,7 @@
/**
*
*/
- public Throwable interpret(boolean stopOnProblem)
- throws NeedMoreException {
+ public Throwable interpret() {
while (true) {
try {
interpretOne();
@@ -552,17 +459,12 @@
} else if (myShouldExit) {
return myOptProblem;
}
- } catch (NeedMoreException nme) {
- throw nme;
-
} catch (Throwable th) {
- if (stopOnProblem) {
- myShouldExit = true;
- myOptProblem = th;
- //reportProblem(th); XXX would be redundant, but which
- // one to keep?
- return th;
- }
+ myShouldExit = true;
+ myOptProblem = th;
+ //reportProblem(th); XXX would be redundant, but which
+ // one to keep?
+ return th;
}
}
}
@@ -612,7 +514,7 @@
/**
*
*/
- static private void errorExit(TextWriter errs, ConstMap props)
+ static /*package*/ void errorExit(TextWriter errs, ConstMap props)
throws IOException {
String oee = (String)props.get("e.onErrorExit", "report");
if ("report".equals(oee)) {
@@ -665,7 +567,12 @@
String name = option.substring(2,equals);
String value = option.substring(equals+1);
sysProps.setProperty(name, value);
-
+
+ } else if ("--interact".equals(option)) {
+ //delegate to the other main
+ InteractiveInterp.main(argArray);
+ return;
+
} else {
throw new IllegalArgumentException(
"Unrecognized option: " + option);
@@ -706,7 +613,7 @@
//proceed normally.
}
- // In order to avoid an upwards dependency, we do the
+ //In order to avoid an upwards dependency, we do the
//tilde-expansion for the trace package, since it doesn't know
//how to do it for itself.
String traceLogDir = sysProps.getProperty("TraceLog_dir", null);
@@ -724,9 +631,8 @@
errs,
new Runner("Main Vat Thread"),
- null,
- null,
- false);
+ null, //optLineFeeder
+ null); //optTopScope
} catch (Throwable th) {
reportProblem(th, errs, true);
errorExit(errs, props);
@@ -735,7 +641,7 @@
TraceController.start(sysProps);
initSwingLnF(props);
- if (null == interp.interpret(! interp.getInteractive())) {
+ if (null == interp.interpret()) {
System.exit(0);
} else {
errorExit(errs, props);
1.2 +45 -68 e/src/jsrc/org/erights/e/elang/interp/Interpreter.java
Index: Interpreter.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/interp/Interpreter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Interpreter.java 2001/07/29 20:57:19 1.1
+++ Interpreter.java 2001/08/05 07:01:24 1.2
@@ -19,90 +19,82 @@
Contributor(s): ______________________________________.
*/
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Properties;
-import javax.swing.LookAndFeel;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-import org.erights.e.develop.exception.ExceptionMgr;
-import org.erights.e.develop.exception.PrintStreamWriter;
-import org.erights.e.develop.exception.ThrowableSugar;
-import org.erights.e.develop.format.StringHelper;
-import org.erights.e.develop.trace.TraceController;
import org.erights.e.elang.evm.EExpr;
import org.erights.e.elang.scope.Scope;
-import org.erights.e.elang.syntax.ELexer;
-import org.erights.e.elang.syntax.EParser;
-import org.erights.e.elang.syntax.FileFeeder;
-import org.erights.e.elang.syntax.LineFeeder;
-import org.erights.e.elang.syntax.NeedMoreException;
-import org.erights.e.elang.syntax.SyntaxException;
-import org.erights.e.elib.base.TextWriter;
-import org.erights.e.elib.prim.E;
-import org.erights.e.elib.prim.Runner;
-import org.erights.e.elib.ref.Ref;
-import org.erights.e.elib.ref.Resolver;
import org.erights.e.elib.tables.ConstList;
import org.erights.e.elib.tables.ConstMap;
-import org.erights.e.elib.tables.Twine;
-import org.erights.e.elib.util.AlreadyDefinedException;
-import org.erights.e.elib.util.ClassCache;
-import org.erights.e.elib.util.TwineException;
-import org.erights.e.meta.java.io.FileGetter;
-import org.erights.e.meta.java.io.FileSugar;
-
/**
- * The interface between a *.e script and its invoker.
+ * Defines the protocol of the object known as "interp" in the privileged
+ * scope.
+ * <p>
+ * This is the interpreted program's interface to the read-eval-print loop
+ * that's driving its evaluation. The spawner of an interpreter will
+ * normally control that interpreter through a different interface, the
+ * InterpLoop.
*
+ * @see InterpLoop
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
+ * @author <a href="mailto:tstanley@cocoon.com">Terry Stanley</a>
*/
public interface Interpreter {
/**
- *
+ * Should an input expression be echoed as expanded to Kernel-E as well
+ * as evaluated?
+ * <p>
+ * If so, the expanded form will be shown in a "# expand: ..." block
*/
- ConstList getArgs();
+ boolean getExpand();
/**
- *
+ * Should problem reports show their Java stack trace as well as their E
+ * stack trace?
+ * <p>
+ * This switch only makes sense while we're interpreting parse trees,
+ * rather than compiling E to jvm byte codes. While we're interpreting,
+ * the Java stack trace tends to large and uninformative. Once we're
+ * compiling, the Java stack trace should be all there is, and should do
+ * both jobs well. So, at that time, this flag will be ignored.
*/
- boolean getExpand();
-
+ boolean getVerbose();
+
/**
+ * Is this a read-eval-print loop for an interactive command line?
+ * <p>
+ * If so, then the top scope should be mutable, each outcome should be
+ * reported, prompts should be generated, and evaluation should continue
+ * after errors.
+ * <p>
* "interactive" is an immutable property, since it's too hard to change.
*/
boolean getInteractive();
/**
- *
+ * A list of Strings that's assumed to be the command line args
+ */
+ ConstList getArgs();
+
+ /**
+ * A map from String (property names) to Strings (property values) that's
+ * assumed to reflect System.getProperties() and the eprops.txt file.
*/
ConstMap getProps();
/**
- *
+ * What scope are top-level expressions evaluated in?
*/
Scope getTopScope();
/**
*
*/
- boolean getVerbose();
-
- /**
- * First clears temporary state (such as results), then does a System.gc()
- */
- void gc();
+ void setExpand(boolean flag);
/**
*
*/
- void setExpand(boolean flag);
+ void setVerbose(boolean flag);
/**
*
@@ -110,13 +102,13 @@
void setTopScope(Scope newScope);
/**
- *
+ * First clears temporary state (such as results), then does a System.gc()
*/
- void setVerbose(boolean flag);
+ void gc();
/**
* Called by an E program to stall the interpreter at the next top level
- * expression, until continueAtTop is called.
+ * expression, until continueAtTop or exitAtTop is called.
*/
void blockAtTop();
@@ -126,10 +118,10 @@
void continueAtTop();
/**
- * Causes the E interpreter to exit the next time its between top-level
+ * Causes the E interpreter to exit the next time it's between top-level
* expression evaluations.
* <p>
- * If optProblem is null, then this is a normal (even if premature)
+ * If optProblem is null, then this is a successful (even if premature)
* exit. Otherwise, it's an exceptional exit complaining of the
* problem. For the main interpreter, a normal exit exits with exitCode
* 0. An exceptional exit complains and exits with exitCode -1.
@@ -138,19 +130,4 @@
* waiting for a continueAtTop.
*/
void exitAtTop(Throwable optProblem);
-
- /**
- * Evals eExpr; if eExpr returns, then print the result in accordance
- * with the flags.
- */
- void evalPrint(EExpr eExpr);
-
- /**
- * Interpret until we're finished. <p>
- *
- * Return null if program succeeded. Otherwise, return the problem with
- * which it failed. A NeedMoreException, though, throws straight
- * through.
- */
- Throwable interpret(boolean stopOnProblem);
}
1.61 +2 -2 e/src/jsrc/org/erights/e/elang/interp/ScopeSetup.java
Index: ScopeSetup.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/interp/ScopeSetup.java,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -r1.60 -r1.61
--- ScopeSetup.java 2001/07/14 12:57:22 1.60
+++ ScopeSetup.java 2001/08/05 07:01:24 1.61
@@ -180,9 +180,9 @@
"<import:org.erights.e.elib.slot.near>" },
{ "PassByCopy", new RuinedSlot(new RuntimeException(
- "XXX PassByCopy auditor not yet implemented")) },
+ "XXX PassByCopy auditor not yet implemented")) },
{ "confined", new RuinedSlot(new RuntimeException(
- "XXX confined auditor not yet implemented")) },
+ "XXX confined auditor not yet implemented")) },
{ "OrderedSpaceMaker", univ,
"<import:org.erights.e.elang.coord.OrderedSpaceMaker>" },
1.1 e/src/jsrc/org/erights/e/elang/interp/InteractiveInterp.java
Index: InteractiveInterp.java
===================================================================
package org.erights.e.elang.interp;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.erights.e.develop.exception.ExceptionMgr;
import org.erights.e.develop.exception.PrintStreamWriter;
import org.erights.e.develop.exception.ThrowableSugar;
import org.erights.e.develop.format.StringHelper;
import org.erights.e.develop.trace.TraceController;
import org.erights.e.elang.evm.EExpr;
import org.erights.e.elang.scope.Scope;
import org.erights.e.elang.syntax.ELexer;
import org.erights.e.elang.syntax.EParser;
import org.erights.e.elang.syntax.FileFeeder;
import org.erights.e.elang.syntax.LineFeeder;
import org.erights.e.elang.syntax.NeedMoreException;
import org.erights.e.elang.syntax.SyntaxException;
import org.erights.e.elib.base.TextWriter;
import org.erights.e.elib.prim.E;
import org.erights.e.elib.prim.Runner;
import org.erights.e.elib.ref.Ref;
import org.erights.e.elib.ref.Resolver;
import org.erights.e.elib.tables.ConstList;
import org.erights.e.elib.tables.ConstMap;
import org.erights.e.elib.tables.Twine;
import org.erights.e.elib.util.AlreadyDefinedException;
import org.erights.e.elib.util.ClassCache;
import org.erights.e.elib.util.TwineException;
import org.erights.e.meta.java.io.FileGetter;
import org.erights.e.meta.java.io.FileSugar;
/**
* The interactive E read-eval-print interpreter loop.
* <p>
* To be replaced with one written in E.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class InteractiveInterp implements Interpreter, InterpLoop {
static boolean uiInititialized = false;
static EExpr[] SubstArgs = null;
static private void initSubst() {
if (null != SubstArgs) {
return;
}
EExpr[] sargs = new EExpr[10];
for (int i = 0; i < sargs.length; i++) {
Twine twine = Twine.fromString("interp getResult(" + i + ")");
sargs[i] = (EExpr)EParser.run(twine);
}
SubstArgs = sargs;
}
private ConstList myArgs;
private ConstMap myProps;
private TextWriter myOuts;
private TextWriter myErrs;
private Runner myRunner;
private EParser myParser;
private Scope[] myTopPov;
private boolean myExpandFlag = false;
private boolean myVerboseFlag = false;
private Object myTopLock = new Object();
private boolean myShouldBlock = false;
private boolean myShouldExit = false;
private Throwable myOptProblem = null;
private Object[] myResults = new Object[10];
/**
* Must call setState() to initialize. This allows subclassing.
*/
/*package*/ InteractiveInterp() {
initSubst();
}
/**
*
*/
/*package*/ void setState(ConstList args,
ConstMap props,
TextWriter outs,
TextWriter errs,
Runner runner,
EParser parser,
Scope[] topPov,
boolean expandFlag,
boolean verboseFlag)
{
myArgs = args;
myProps = props;
myOuts = outs;
myErrs = errs;
myRunner = runner;
myParser = parser;
myTopPov = topPov;
myExpandFlag = expandFlag;
myVerboseFlag = verboseFlag;
}
/**
*
*/
public ConstList getArgs() {
return myArgs;
}
/**
*
*/
public boolean getExpand() {
return myExpandFlag;
}
/**
*
*/
public boolean getInteractive() {
return true;
}
/**
*
*/
public ConstMap getProps() {
return myProps;
}
/**
*
*/
public Scope getTopScope() {
return myTopPov[0];
}
/**
*
*/
public boolean getVerbose() {
return myVerboseFlag;
}
/**
*
*/
public Object getResult(int i) {
return myResults[i];
}
/**
*
*/
public void gc() {
for (int i = 0; i < myResults.length; i++) {
myResults[i] = null;
}
System.gc();
}
/**
*
*/
public void setExpand(boolean flag) {
myExpandFlag = flag;
}
/**
*
*/
public void setTopScope(Scope newScope) {
myTopPov[0] = newScope;
}
/**
*
*/
public void setVerbose(boolean flag) {
myVerboseFlag = flag;
}
/**
* Creates an E interpreter.
*
* @param args; the command line arguments. If 'optLineFeeder' is null,
* the information
* necessary to construct it are first extracted from args, and
* only the remaining args are stored.
*
* @param props A ConstMap thought to reflect System.getProperties
*
* @param outs; where normal output should go
* @param errs; where diagnostic output should go (may be the same
* as 'outs')
*
* @param optLineFeeder nullOk; if null, derived by extracting the first
* argument of args as the name of a file to interpret.
*
* @param optTopScope nullOk; if null, the standard initial scope is
* constructed.
*
* @param partialFlag What to do on end of file. If false, throws
* SyntaxException. If true (meaning a partial parse is ok), throws
* NeedMoreException.
*/
static public InteractiveInterp make(ConstList args,
ConstMap props,
TextWriter outs,
TextWriter errs,
Runner runner,
LineFeeder optLineFeeder,
Scope optTopScope,
boolean partialFlag)
throws IOException, AlreadyDefinedException {
if (optLineFeeder == null) {
BufferedReader ins = PrintStreamWriter.in();
optLineFeeder = new FileFeeder("", ins, outs, null);
}
ELexer lexer = new ELexer(optLineFeeder,
partialFlag,
Interp.testProp(props, "e.enable.notabs"));
EParser parser = new EParser(props,
lexer,
Interp.testProp(props, "e.interp.parseSpam"),
true);
if (optLineFeeder instanceof FileFeeder) {
((FileFeeder)optLineFeeder).setParser(parser);
}
Object[] promise = Ref.promise();
Ref interpPromise = (Ref)promise[0];
Resolver interpResolver = (Resolver)promise[1];
if (optTopScope == null) {
optTopScope = ScopeSetup.privileged(true,
outs,
errs,
props,
interpPromise);
}
Scope[] topPov = optTopScope.newPov();
boolean expandFlag = Interp.testProp(props, "e.interp.expand");
boolean verboseFlag = Interp.testProp(props, "e.interp.verbose");
InteractiveInterp result = new InteractiveInterp();
result.setState(args,
props,
outs,
errs,
runner,
parser,
topPov,
expandFlag,
verboseFlag);
interpResolver.resolve(result);
return result;
}
/**
*
*/
public void blockAtTop() {
synchronized(myTopLock) {
myShouldBlock = true;
}
}
/**
*
*/
public void continueAtTop() {
synchronized(myTopLock) {
myShouldBlock = false;
myTopLock.notifyAll();
}
}
/**
* Not yet tested, because Elmer doesn't currently interact correctly
* with interpreter exiting.
*/
public void exitAtTop(Throwable optProblem) {
synchronized(myTopLock) {
myShouldBlock = false;
myShouldExit = true;
myOptProblem = optProblem;
myTopLock.notifyAll();
}
}
/**
*
*/
public void reportProblem(Throwable t) {
Interp.reportProblem(t, myErrs, myVerboseFlag);
}
/**
*
*/
public void setSource(Twine newSource) {
myParser.setSource(newSource);
}
/**
*
*/
private void pushResult(Object result) {
System.arraycopy(myResults, 0, myResults, 1, 9);
myResults[0] = result;
}
/**
* Called while the vatLock is held.
*
* @see org.erights.e.elib.prim.Runner#callNow
*/
public void evalPrint(EExpr eExpr) {
myShouldBlock = false;
myShouldExit = false;
myOptProblem = null;
try {
if (myExpandFlag) {
myOuts.print("# expansion: ");
eExpr.lnPrintOn(myOuts.indent("# "));
myOuts.println();
myOuts.println();
}
Object result = null;
try {
result = Ref.resolution(eExpr.eval(myTopPov));
pushResult(result);
} catch (Throwable t) {
result = Ref.broken(t);
pushResult(result);
throw t;
}
if (result != null) {
Interp.commentBlock(myOuts, "value").quote(result);
myOuts.println();
myOuts.println();
}
myOuts.flush();
myErrs.flush();
} catch (Throwable t) {
throw ExceptionMgr.asSafe(t);
}
}
/**
*
*/
private void interpretOne() throws NeedMoreException {
try {
EExpr optExpr = (EExpr)myParser.optParse();
if (null != optExpr) {
optExpr = optExpr.substitute(SubstArgs);
Object[] args = { optExpr };
myRunner.callNow(this, "evalPrint", args);
}
} catch (Throwable t) {
Throwable leaf = ThrowableSugar.leaf(t);
if (leaf instanceof NeedMoreException) {
throw (NeedMoreException)leaf;
}
reportProblem(t);
throw ExceptionMgr.asSafe(t);
} finally {
try {
myOuts.flush();
myErrs.flush();
} catch (IOException iox) {
ExceptionMgr.reportException(iox);
throw ExceptionMgr.asSafe(iox);
}
synchronized(myTopLock) {
while (myShouldBlock) {
try {
myTopLock.wait();
} catch (InterruptedException ie) {
//ignored on purpose. Our enclosing while loop
//makes this safe
}
}
}
}
}
/**
*
*/
public Throwable interpret() throws NeedMoreException {
while (true) {
try {
interpretOne();
if (myParser.isEndOfFile()) {
return null;
} else if (myShouldExit) {
return myOptProblem;
}
} catch (NeedMoreException nme) {
throw nme;
} catch (Throwable th) {
//already reported. Just go on.
}
}
}
/**
*
*/
public void printOn(TextWriter out) throws IOException {
out.print("<interactive interp>");
}
/**
*
*/
static public void main(String[] argArray)
throws IOException, AlreadyDefinedException,
UnsupportedLookAndFeelException, ClassNotFoundException,
InstantiationException, IllegalAccessException
{
ConstList args = ConstList.fromArray(argArray);
Properties sysProps = System.getProperties();
TextWriter outs = new TextWriter(PrintStreamWriter.out());
TextWriter errs = new TextWriter(PrintStreamWriter.err());
while (args.size() >= 1) {
String option = (String)args.get(0);
// "-" isn't considered an option
if (option.length() < 2 || option.charAt(0) != '-') {
break;
}
args = args.run(1, args.size());
if (option.startsWith("-D")) {
//Normally, all "-D..=.." options would occur to the left of
//the main class name, and therefore be processed by the Java
//launcher before launching the main class. However, this
//may be difficult in some IDEs (like Cafe), so we also
//process such options ourselves.
int equals = option.indexOf('=');
if (equals == -1) {
throw new IllegalArgumentException(
"Property spec missing '=': " + option);
}
String name = option.substring(2,equals);
String value = option.substring(equals+1);
sysProps.setProperty(name, value);
} else if ("--interact".equals(option)) {
//ignored, since it's already what we're doing
} else {
throw new IllegalArgumentException(
"Unrecognized option: " + option);
}
}
String eHome = sysProps.getProperty("e.home");
if (null == eHome) {
eHome = ".";
}
File eHomeDir = FileGetter.get(eHome);
File epropsFile = FileSugar.get(eHomeDir, "eprops.txt");
if (epropsFile.exists()) {
Properties eprops = new Properties();
FileInputStream ins = new FileInputStream(epropsFile);
try {
eprops.load(ins);
} finally {
ins.close();
}
Enumeration iter = eprops.propertyNames();
while (iter.hasMoreElements()) {
String key = (String)iter.nextElement();
if (! sysProps.containsKey(key)) {
sysProps.setProperty(key, eprops.getProperty(key));
}
}
}
// In order to avoid an upwards dependency, we do the
//tilde-expansion for the trace package, since it doesn't know
//how to do it for itself.
String traceLogDir = sysProps.getProperty("TraceLog_dir", null);
if (null != traceLogDir) {
traceLogDir = FileGetter.normalize(traceLogDir);
sysProps.setProperty("TraceLog_dir", traceLogDir);
}
ConstMap props = ConstMap.fromProperties(sysProps);
InteractiveInterp interp = null;
try {
interp = InteractiveInterp.make(args,
props,
outs,
errs,
new Runner("Main Vat Thread"),
null, //optLineFeeder
null, //optTopScope
false); //partialFlag
} catch (Throwable th) {
Interp.reportProblem(th, errs, true);
Interp.errorExit(errs, props);
}
TraceController.start(sysProps);
Interp.initSwingLnF(props);
if (null == interp.interpret()) {
System.exit(0);
} else {
Interp.errorExit(errs, props);
}
}
}
1.1 e/src/jsrc/org/erights/e/elang/interp/InterpLoop.java
Index: InterpLoop.java
===================================================================
package org.erights.e.elang.interp;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elib.tables.Twine;
/**
* The interface for controlling a read-eval-print loop from the "outside".
*
* @see Interpreter
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
* @author <a href="mailto:tstanley@cocoon.com">Terry Stanley</a>
*/
public interface InterpLoop {
/**
* Changes the lexer to read lines from this source text rather than
* wherever it was initially reading from.
*/
void setSource(Twine newSource);
/**
* Interpret until we're finished. <p>
*
* Return null if program succeeded. Otherwise, return the problem with
* which it failed. A NeedMoreException, though, throws straight
* through.
*/
Throwable interpret();
}
1.29 +16 -14 e/src/jsrc/org/erights/e/ui/elmer/EInterpAdapter.java
Index: EInterpAdapter.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/ui/elmer/EInterpAdapter.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- EInterpAdapter.java 2001/04/13 08:08:35 1.28
+++ EInterpAdapter.java 2001/08/05 07:01:25 1.29
@@ -29,7 +29,8 @@
import org.erights.e.develop.exception.ThrowableSugar;
import org.erights.e.develop.format.StringHelper;
import org.erights.e.elang.scope.Scope;
-import org.erights.e.elang.interp.Interp;
+import org.erights.e.elang.interp.InteractiveInterp;
+import org.erights.e.elang.interp.InterpLoop;
import org.erights.e.elang.syntax.NeedMoreException;
import org.erights.e.elang.syntax.TwineFeeder;
import org.erights.e.elib.base.SourceSpan;
@@ -53,7 +54,7 @@
private JTextArea myTextArea;
private StringBuffer myOutBuffer;
private TextWriter myOuts;
- private Interp myInterp;
+ private InterpLoop myInterp;
/**
*
@@ -69,25 +70,26 @@
String[] args = { "elmer" };
Properties props = new Properties(System.getProperties());
- props.setProperty("e.interp.interactive", "true");
try {
TwineFeeder sacrificial = new TwineFeeder(Twine.fromString(""));
- myInterp = Interp.make(ConstList.fromArray(args),
- ConstMap.fromProperties(props),
- myOuts,
- myOuts, //errs
+ myInterp = InteractiveInterp.make(
+ ConstList.fromArray(args),
+ ConstMap.fromProperties(props),
+ myOuts,
+ myOuts, //errs
- new Runner("Elmer Vat Thread"),
- sacrificial, //never used
- null,
- true);
+ new Runner("Elmer Vat Thread"),
+ sacrificial, //never used, but suppresses
+ //filename processing
+ null, //optTopScope
+ true); //partialFlag
} catch (AlreadyDefinedException ade) {
throw ThrowableSugar.backtrace(ade, "can't happen");
} catch (IOException iox) {
throw ThrowableSugar.backtrace(iox, "can't happen");
}
- Scope topScope = myInterp.getTopScope();
- myInterp.setTopScope(topScope.bindFinal("elmer", myElmer));
+ //Scope topScope = myInterp.getTopScope();
+ //myInterp.setTopScope(topScope.bindFinal("elmer", myElmer));
}
/**
@@ -133,7 +135,7 @@
SourceSpan span = null; //for now
myInterp.setSource(Twine.fromString(source, span));
try {
- myInterp.interpret(true);
+ myInterp.interpret();
} catch (NeedMoreException nme) {
String msg = left + "> ";