[e-cvs] cvs commit: e/src/test/esrc pasteRun.updoc proxycommtest.updoc title.updoc

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Thu, 8 Nov 2001 20:17:23 -0500


markm       01/11/08 20:17:23

  Modified:    src      Makefile
               src/esrc/scripts ButtonPointer.e
               src/jsrc Makefile
               src/jsrc/org/erights/e/elang/evm AssignExpr.java
                        CallExpr.java CatchExpr.java CdrPattern.java
                        DefineExpr.java EExpr.java EImpl.java
                        EImplByProxy.java EMeta.java EMethod.java
                        ENode.java EScript.java EscapeExpr.java
                        Evaluator.java FinalPattern.java FinallyExpr.java
                        HideExpr.java IfExpr.java IgnorePattern.java
                        ListPattern.java LiteralExpr.java
                        MatchBindExpr.java Matcher.java MetaExpr.java
                        NounExpr.java ObjectExpr.java Pattern.java
                        QuasiLiteralExpr.java QuasiLiteralPatt.java
                        QuasiPatternExpr.java QuasiPatternPatt.java
                        ScopeExpr.java SendExpr.java SeqExpr.java
                        SlotExpr.java StaticScope.java SuchThatPattern.java
                        VarPattern.java
               src/jsrc/org/erights/e/elang/interp Help.java
                        InteractiveInterp.java Interp.java
                        LazyEvalSlot.java LoaderScope.java
                        PackageScope.java ScopeSetup.java
                        UnsafeLoaderScope.java
               src/jsrc/org/erights/e/elang/scope Scope.java
               src/jsrc/org/erights/e/elang/syntax EBuilder.java
               src/jsrc/org/erights/e/elang/visitors
                        AlphaRenameVisitor.java CopyVisitor.java
                        ETreeVisitor.java
               src/jsrc/org/erights/e/elib/base Callable.java Ejection.java
                        MethodNode.java ParseNode.java
               src/jsrc/org/erights/e/elib/prim JavaMemberNode.java
               src/jsrc/org/erights/e/elib/tables EMap.java Equalizer.java
               src/test/esrc pasteRun.updoc proxycommtest.updoc title.updoc
  Removed:     src/jsrc/org/erights/e/elang/scope MutableScope.java
                        ScopeImpl.java
  Log:
  The not-quite working integration of 0.8.10alpha1 and Dean's transformer: 0.8.9t.1a

Revision  Changes    Path
1.121     +8 -8      e/src/Makefile

Index: Makefile
===================================================================
RCS file: /cvs/e/src/Makefile,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -r1.120 -r1.121
--- Makefile	2001/11/06 06:27:32	1.120
+++ Makefile	2001/11/09 01:17:20	1.121
@@ -7,8 +7,8 @@
 
 # Prefix tagging this release's attributes
 PREFIX=E
-DOTVER=0.8.10beta1
-TAGVER=0_8_10beta1
+DOTVER=0.8.10beta2
+TAGVER=0_8_10beta2
 RELEASE=working
 
 TOP=..
@@ -27,9 +27,9 @@
 	-rm -rf $(TOP)/dist
 	mkdir -p $(TOP)/dist
 	echo $(DOTVER) > $(TOP)/dist/eVersion.txt
-	cp -r $(TOP)/src/bin $(TOP)/dist/bin
-	cp -r $(TOP)/src/esrc/scripts $(TOP)/dist/scripts
-	cp -r $(TOP)/src/elisp/* $(TOP)/dist/scripts
+	cp -rf $(TOP)/src/bin $(TOP)/dist/bin
+	cp -rf $(TOP)/src/esrc/scripts $(TOP)/dist/scripts
+	cp -rf $(TOP)/src/elisp/* $(TOP)/dist/scripts
 	-rm -rf `find $(TOP)/dist -name CVS`
 	mkdir $(TOP)/dist/bin/$(PLATDIR)
 	(cd csrc/byaccj; $(MAKE) all install)
@@ -37,8 +37,8 @@
 export:
 	-rm -rf $(TOP)/export
 	mkdir --parents $(TOP)/export/e
-	cp -r $(TOP)/dist $(TOP)/export/dist
-	cp -r $(TOP)/src $(TOP)/export/e/src
+	cp -rf $(TOP)/dist $(TOP)/export/dist
+	cp -rf $(TOP)/src $(TOP)/export/e/src
 	-rm -rf `find $(TOP)/export -name CVS`
 	-rm -rf `find $(TOP)/export -name makeout`
 	-rm -rf `find $(TOP)/export -name cvsout`
@@ -78,7 +78,7 @@
 endif
 	(cd $(TOP)/export/dist; tar czf $(UPFIX2)-nix-$(DOTVER).tar.gz .)
 	(cd $(TOP)/export;      tar czf $(UPFIX1)-src-$(DOTVER).tar.gz e)
-	cp $(TOP)/export/dist/e.jar $(TOP)/tarballs
+	cp -f $(TOP)/export/dist/e.jar $(TOP)/tarballs
 #	-rm -rf $(TOP)/export
 
 ckversion:



1.16      +98 -76    e/src/esrc/scripts/ButtonPointer.e

Index: ButtonPointer.e
===================================================================
RCS file: /cvs/e/src/esrc/scripts/ButtonPointer.e,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- ButtonPointer.e	2001/07/14 12:57:20	1.15
+++ ButtonPointer.e	2001/11/09 01:17:20	1.16
@@ -1,16 +1,22 @@
 #!/usr/bin/env e
 
+def root
+
 def complain(complaint) {
     # throw(complaint)
     println(complaint)
 }
 
+def traceln(msg) {
+    println(msg)
+}
+
 def editFile(file, varName, newValue) {
     if (file exists()) {
         def text := file getText()
         if (text =~ `@left<!-- #BeginEditable "$varName" -->@oldValue<!-- #EndEditable -->@right` &&
-            oldValue != newValue) {
-
+              oldValue != newValue) {
+            
             file setText(`$left<!-- #BeginEditable "$varName" -->$newValue<!-- #EndEditable -->$right`)
         }
     } else {
@@ -18,11 +24,11 @@
     }
 }
 
-    ? def f := <d:/e/doc/toc.txt>
-    # value: <file:d:/e/doc/toc.txt>
+? def f := <c:/e/doc/toc.txt>
+# value: <file:c:/e/doc/toc.txt>
 
-    ? def tr := f textReader()
-    # value: java.io.BufferedReader@1cd7ae
+? def tr := f textReader()
+# value: java.io.BufferedReader@1cd7ae
 
 def getLine(tr) :any {
     while (true) {
@@ -41,16 +47,16 @@
     }
 }
 
-    ? getLine(tr)
-    # value: [1, elib/]
+? getLine(tr)
+# value: [1, elib/]
 
-    ? getLine(tr)
-    # value: [2, capability/]
+? getLine(tr)
+# value: [2, capability/]
 
-    ? getLine(tr)
-    # value: [3, ode/]
+? getLine(tr)
+# value: [3, ode/]
 
-    ? tr close
+? tr close
 
 def walkToc(wdir) {
     def tocReader := wdir["toc.txt"] textReader()
@@ -72,7 +78,7 @@
     }
     while (true) {
         def [level, name] := getLine(tocReader)
-
+        
         if (level > prevLevel) {
             # name is the first child of prev.
             require(level == prevLevel + 1,
@@ -80,7 +86,7 @@
             nest()
             # 'parent[name]' is redundant.  Oh well.
             parent setDownButton(parent[name])
-
+            
         } else {
             while (prevLevel > level) {
                 # name is the next sibling of an ancestor of prev
@@ -110,16 +116,18 @@
     [filename(0,i+1), filename(i+1, filename size())]
 }
 
-    ? splitName("foo/bar/baz")
-    # value: [foo/bar/, baz]
+? splitName("foo/bar/baz")
+# value: [foo/bar/, baz]
 
-    ? splitName("foo.bar")
-    # value: [, foo.bar]
+? splitName("foo.bar")
+# value: [, foo.bar]
 
-    ? splitName("foo/bar/")
-    # value: [foo/, bar/]
+? splitName("foo/bar/")
+# value: [foo/, bar/]
 
-def relativeURL(var src, var target) :any {
+def relativeURL(osrc, otarget) :any {
+    var src := osrc
+    var target := otarget
     if (src =~ `<@tmp>`) {
         src := tmp
     }
@@ -138,37 +146,39 @@
             thunk{`$src should be at end`})
     def `$src@rest` := target
     buf append(rest)
-    def result := "" + buf snapshot()
+    var result := "" + buf snapshot()
     if (result endsWith("/")) {
-        result + "index.html"
+        result += "index.html"
     } else {
         result
     }
+    traceln(`$result = relativeURL($osrc, $otarget)`)
+    result
 }
 
-    ? relativeURL("foo/bar", "baz/zip")
-    # value: ../baz/zip
+? relativeURL("foo/bar", "baz/zip")
+# value: ../baz/zip
 
-    ? relativeURL("foo/bar", "baz/zip/")
-    # value: ../baz/zip/index.html
+? relativeURL("foo/bar", "baz/zip/")
+# value: ../baz/zip/index.html
 
-    ? relativeURL("foo/bar", "foo/zip")
-    # value: zip
+? relativeURL("foo/bar", "foo/zip")
+# value: zip
 
-    ? relativeURL("foo/bar", "foo/bar/zip")
-    # problem: required condition failed
-    #
-    #   <statics of org.erights.e.elang.interp.Thrower>(required condition failed)
-    #   <require0>(false, required condition failed)
-    #   <require0>(false)
-    #   <relativeURL>(foo/bar, foo/bar/zip)
-    #   <interp> evalPrint(e`relativeURL run("foo/bar", "foo/bar/zip")`)
+? relativeURL("foo/bar", "foo/bar/zip")
+# problem: required condition failed
+#
+#   <statics of org.erights.e.elang.interp.Thrower>(required condition failed)
+#   <require0>(false, required condition failed)
+#   <require0>(false)
+#   <relativeURL>(foo/bar, foo/bar/zip)
+#   <interp> evalPrint(e`relativeURL run("foo/bar", "foo/bar/zip")`)
 
-    ? relativeURL("foo/bar/", "foo/bar/zip")
-    # value: zip
+? relativeURL("foo/bar/", "foo/bar/zip")
+# value: zip
 
-    ? relativeURL("foo/bar/", "foo/")
-    # value: ../index.html
+? relativeURL("foo/bar/", "foo/")
+# value: ../index.html
 
 class FileWrapperMaker(filedir) :any {
     def file := if (filedir isDirectory()) {
@@ -194,13 +204,13 @@
             def base := ""+filedir
             def text := if (wfile == null) {
                 `<img src="${
-                relativeURL(base, "<file:d:/e/doc/images/next-gray.gif>")
+                    relativeURL(base, `<$root/images/next-gray.gif>`)
                 }" width="64" height="32">`
             } else {
                 `<a href="${
-                relativeURL(base, ""+wfile)
+                    relativeURL(base, ""+wfile)
                 }"><img src="${
-                relativeURL(base, "<file:d:/e/doc/images/next.gif>")
+                    relativeURL(base, `<$root/images/next.gif>`)
                 }" width="64" height="32" alt="On to: ${wfile getTitle()}" border="0"></a>`
             }
             editFile(file, "NextButton", text)
@@ -209,13 +219,13 @@
             def base := ""+filedir
             def text := if (wfile == null) {
                 `<img src="${
-                relativeURL(base, "<file:d:/e/doc/images/prev-gray.gif>")
+                    relativeURL(base, `<$root/images/prev-gray.gif>`)
                 }" width="64" height="32">`
             } else {
                 `<a href="${
-                relativeURL(base, ""+wfile)
+                    relativeURL(base, ""+wfile)
                 }"><img src="${
-                relativeURL(base, "<file:d:/e/doc/images/prev.gif>")
+                    relativeURL(base, `<$root/images/prev.gif>`)
                 }" width="64" height="32" alt="Back to: ${wfile getTitle()}" border="0"></a>`
             }
             editFile(file, "PrevButton", text)
@@ -224,15 +234,15 @@
             def base := ""+filedir
             def text := if (wfile == null) { "" } else {
                 `<a href="${
-                relativeURL(base, ""+wfile)
+                    relativeURL(base, ""+wfile)
                 }"><img src="${
-                relativeURL(base, "<file:d:/e/doc/images/first.gif>")
+                    relativeURL(base, `<$root/images/first.gif>`)
                 }" width="32" height="64" alt="1st child: ${wfile getTitle()}" border="0"></a>`
             }
             editFile(file, "FirstButton", text)
         }
         to setUpButton(wdir) {
-            def `<file:d:/e/doc/@{var path}>` := ""+wdir
+            def `<$root/@{var path}>` := (""+wdir)
             def list := [] diverge()
             while (path =~ `@dir/@rest`) {
                 list push(dir)
@@ -245,7 +255,7 @@
             def adjust := if (filedir isDirectory()) { 0 } else { 1 }
             for i in 0..!levels {
                 buf append(`/&nbsp;<a href="${
-                "../" * (levels - i - adjust)
+                    "../" * (levels - i - adjust)
                 }index.html">${list[i]}</a>&nbsp;`)
             }
             editFile(file, "Path", buf snapshot())
@@ -255,37 +265,49 @@
         delegate { filedir }
     }
 }
-
-    ? def welib := FileWrapperMaker new(<d:/e/doc/elib/>)
-    # value: <file:d:/e/doc/elib/>
-
-    ? welib.title
-    # value: ELib: Local and Remote
 
-    ? def winsrc := FileWrapperMaker new(<d:/e/doc/download/windows-src.html>)
-    # value: <file:d:/e/doc/download/windows-src.html>
+? def welib := FileWrapperMaker new(<c:/e/doc/elib/>)
+# value: <file:c:/e/doc/elib/>
 
-    ? welib.downButton := null
-    ? welib.downButton := winsrc
-    # value: <file:d:/e/doc/download/windows-src.html>
+? welib.title
+# value: ELib: Local and Remote
 
-    ?
-    ? def unixbin := FileWrapperMaker new(<d:/e/doc/download/unix-bin.html>)
-    # value: <file:d:/e/doc/download/unix-bin.html>
+? def winsrc := FileWrapperMaker new(<c:/e/doc/download/windows-src.html>)
+# value: <file:c:/e/doc/download/windows-src.html>
 
-    ? winsrc.nextButton := null
-    ? winsrc.nextButton := unixbin
-    # value: <file:d:/e/doc/download/unix-bin.html>
-
-    ? unixbin.prevButton := winsrc
-    # value: <file:d:/e/doc/download/windows-src.html>
+? welib.downButton := null
+? welib.downButton := winsrc
+# value: <file:c:/e/doc/download/windows-src.html>
+
+?
+? def unixbin := FileWrapperMaker new(<c:/e/doc/download/unix-bin.html>)
+# value: <file:c:/e/doc/download/unix-bin.html>
+
+? winsrc.nextButton := null
+? winsrc.nextButton := unixbin
+# value: <file:c:/e/doc/download/unix-bin.html>
+
+? unixbin.prevButton := winsrc
+# value: <file:c:/e/doc/download/windows-src.html>
+
+? unixbin.prevButton := null
+? unixbin.upButton := FileWrapperMaker new(<c:/e/doc/download/>)
+# value: <file:c:/e/doc/download/>
+
+def fileName
+if (interp getArgs() =~ [bind fileName]) {
+    # we're done
+} else {
+    # kludge around lack of args in eBrowser's Run action
+    def bind fileName := "c:/e/doc"
+}
 
-    ? unixbin.prevButton := null
-    ? unixbin.upButton := FileWrapperMaker new(<d:/e/doc/download/>)
-    # value: <file:d:/e/doc/download/>
+def wdir := <file: fileName>
+# XXX should use 'wdir getPath()' rather that ' ""+wdir'
+def `<@{bind root}/>` := ""+wdir
 
 try {
-    walkToc(FileWrapperMaker new(<d:/e/doc>))
+    walkToc(FileWrapperMaker new(wdir))
 } catch problem {
     println(problem javaStack())
     println(problem eStack())



1.59      +2 -2      e/src/jsrc/Makefile

Index: Makefile
===================================================================
RCS file: /cvs/e/src/jsrc/Makefile,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -r1.58 -r1.59
--- Makefile	2001/11/04 03:12:28	1.58
+++ Makefile	2001/11/09 01:17:20	1.59
@@ -16,8 +16,8 @@
 setup:
 	-rm -rf $(TOP)/classes/*
 	mkdir -p $(TOP)/classes/
-	cp -r $(TOP)/src/esrc/* $(TOP)/classes/
-	cp -r $(TOP)/src/bin/resources/* $(TOP)/classes/
+	cp -rf $(TOP)/src/esrc/* $(TOP)/classes/
+	cp -rf $(TOP)/src/bin/resources/* $(TOP)/classes/
 	-rm -rf `find $(TOP)/classes -name CVS`
 	(cd $(TOP)/classes; jar xf ../src/bin/jars/hydro.jar)
 	-rm -rf $(TOP)/classes/META-INF



1.28      +6 -9      e/src/jsrc/org/erights/e/elang/evm/AssignExpr.java

Index: AssignExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/AssignExpr.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- AssignExpr.java	2001/09/09 07:57:02	1.27
+++ AssignExpr.java	2001/11/09 01:17:20	1.28
@@ -18,7 +18,7 @@
 
 Contributor(s): ______________________________________.
 */
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
@@ -69,20 +69,17 @@
     /*package*/ StaticScope computeStaticScope() {
         FlexMap leftSet = FlexMap.fromTypes(String.class, Void.class);
         leftSet.put(myNoun.name(), null);
-        StaticScope leftScope = new StaticScope(StaticScope.EmptyMap,
-                                                leftSet.snapshot(),
-                                                false,
-                                                StaticScope.EmptyMap);
+        StaticScope leftScope = StaticScope.scopeAssign(leftSet.snapshot());
         return leftScope.add(myRValue.staticScope());
     }
 
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
-        Object result = myRValue.subEval(pov, false);
-        try {
-            pov[0].put(myNoun.name(), result);
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
+        Object result = myRValue.subEval(ctx, true);
+		try {
+            myNoun.assign(ctx, result);
         } catch (Exception ex) {
             throw new NestedException("assigning " + myNoun.name(), ex);
         }



1.30      +5 -5      e/src/jsrc/org/erights/e/elang/evm/CallExpr.java

Index: CallExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/CallExpr.java,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- CallExpr.java	2001/09/07 05:49:20	1.29
+++ CallExpr.java	2001/11/09 01:17:20	1.30
@@ -21,7 +21,7 @@
 
 import org.erights.e.develop.exception.ExceptionMgr;
 import org.erights.e.develop.exception.ThrowableSugar;
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.E;
@@ -86,11 +86,11 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
-        Object receiver = myRecipient.subEval(pov, false);
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
+        Object receiver = myRecipient.subEval(ctx, true);
         Object[] argVals = new Object[myArgs.length];
-        for (int i = 0; i < argVals.length; i++) {
-            argVals[i] = myArgs[i].subEval(pov, false);
+        for (int i = 0, max = argVals.length; i < max; i++) {
+            argVals[i] = myArgs[i].subEval(ctx, true);
         }
         try {
             Object result = E.callAll(receiver, myVerb, argVals);



1.16      +5 -7      e/src/jsrc/org/erights/e/elang/evm/CatchExpr.java

Index: CatchExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/CatchExpr.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- CatchExpr.java	2001/09/07 05:49:20	1.15
+++ CatchExpr.java	2001/11/09 01:17:20	1.16
@@ -20,7 +20,7 @@
 */
 
 import org.erights.e.develop.exception.ExceptionMgr;
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
@@ -79,14 +79,12 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
         try {
-            return myAttempt.subEval(pov[0].sprout().newPov(), onlyFlag);
-
+            return myAttempt.subEval(ctx, forValue);
         } catch (Exception ex) {
-            Scope catchScope = pov[0].sprout();
             try {
-                catchScope = myPattern.testMatch(catchScope, ex, null);
+                myPattern.testMatch(ctx, ex, null);
             } catch (Exception ex2) {
                 //Subtle but important semantic point: Not only do we rethrow
                 //the original problem if the catch-pattern fails to match,
@@ -98,7 +96,7 @@
                 //problem.
                 throw ExceptionMgr.asSafe(ex);
             }
-            return myCatcher.subEval(catchScope.newPov(), onlyFlag);
+            return myCatcher.subEval(ctx, forValue);
         }
     }
 



1.15      +6 -7      e/src/jsrc/org/erights/e/elang/evm/CdrPattern.java

Index: CdrPattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/CdrPattern.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- CdrPattern.java	2001/09/07 05:49:20	1.14
+++ CdrPattern.java	2001/11/09 01:17:20	1.15
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.Thrower;
@@ -99,7 +99,7 @@
     /**
      *
      */
-    /*package*/ Scope testMatch(Scope scope,
+    /*package*/ void testMatch(EvalContext ctx,
                                 Object specimen,
                                 OneArgFunc optEjector)
     {
@@ -129,14 +129,13 @@
                                   " size list doesn't match a >= " +
                                   start.length + " size list pattern");
         }
-        for (int i = 0; i < start.length; i++) {
-            scope = (Scope)start[i].testMatch(scope,
-                                              list.get(i),
-                                              optEjector);
+        for (int i = 0, max = start.length; i < max; i++) {
+            start[i].testMatch(ctx, list.get(i), optEjector);
         }
         EList rest = list.run(start.length, list.size());
-        return myRest.testMatch(scope, rest, optEjector);
+        myRest.testMatch(ctx, rest, optEjector);
     }
+
 
     /**
      *



1.29      +5 -6      e/src/jsrc/org/erights/e/elang/evm/DefineExpr.java

Index: DefineExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/DefineExpr.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- DefineExpr.java	2001/09/07 05:49:20	1.28
+++ DefineExpr.java	2001/11/09 01:17:20	1.29
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
@@ -93,12 +93,11 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
         //because of the well-formedness rule, we may evaluate in the wrong
         //order without effect.
-        Object result = myRValue.subEval(pov, false);
-        pov[0] = myPattern.testMatch(pov[0], result, null);
-        //if we survive, then...
+        Object result = myRValue.subEval(ctx, true);
+        myPattern.testMatch(ctx, result, null);
         return result;
     }
 
@@ -106,7 +105,7 @@
      *
      */
     public boolean matchBind(Object[] args,
-                             Object specimen,
+                              Object specimen,
                              FlexList bindings)
     {
         DefineExpr other;



1.28      +38 -29    e/src/jsrc/org/erights/e/elang/evm/EExpr.java

Index: EExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/EExpr.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- EExpr.java	2001/09/07 05:49:20	1.27
+++ EExpr.java	2001/11/09 01:17:20	1.28
@@ -18,15 +18,18 @@
 
 Contributor(s): ______________________________________.
 */
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.scope.Scope;
-import org.erights.e.elang.scope.UndefinedVariableException;
+import org.erights.e.elang.scope.ScopeMap;
+import org.erights.e.elang.visitors.BindFramesVisitor;
 import org.erights.e.elang.visitors.SubstVisitor;
-import org.erights.e.elib.base.ParseNode;
+
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.E;
 import org.erights.e.elib.tables.ConstMap;
 
 import java.io.IOException;
+import java.util.List;
 
 
 /**
@@ -35,14 +38,13 @@
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public abstract class EExpr extends ParseNode implements ENode {
-
-    private StaticScope myOptStaticScope = null;
+public abstract class EExpr extends ENode {
 
+    static public EExpr TheLastTransformed = new NounExpr("none");
     /**
      *
      */
-    /*package*/ EExpr() {}
+    protected EExpr() {}
 
     /**
      * @see #subPrintOn
@@ -69,32 +71,29 @@
     /*package*/ abstract StaticScope computeStaticScope();
 
     /**
-     * Used to evaluate this expression to a value in scope pov[0],
-     * and to place the successor scope in pov[0].
+     * Used to evaluate this expression to a value in scope.
      */
-    public Object eval(Scope[] pov) {
-        Scope scope = pov[0];
-        StaticScope ss = staticScope();
-        ConstMap namesUsed = ss.namesRead().or(ss.namesSet());
-        String[] keys = (String[])namesUsed.getKeys(String.class);
-        for (int i = 0; i < keys.length; i++) {
-            if (null == scope.getSlot(keys[i])) {
-                throw new UndefinedVariableException(keys[i] + " not in scope");
-            }
-        }
-        return subEval(pov, false);
+    public Object eval(Scope scope) {
+        ScopeMap map = scope.scopeMap();
+        BindFramesVisitor vis = BindFramesVisitor.make(scope);
+        EExpr realExpr = vis.xformEExpr(this);
+        EvalContext ctx = scope.newContext(vis.maxLocals());
+        Object result = realExpr.subEval(ctx, true);
+	// HACK expose the internal transformed expression
+	TheLastTransformed = realExpr;
+        return result;
     }
 
     /**
      * The recursive part that does the work
      */
-    /*package*/ abstract Object subEval(Scope[] pov, boolean onlyFlag);
+    /*package*/ abstract Object subEval(EvalContext ctx, boolean forValue);
 
     /**
      * Like subEval, but returns the result coerced to a boolean.
      */
-    /*package*/ boolean evalBool(Scope[] pov) {
-        return E.asBoolean(subEval(pov, false));
+    /*package*/ boolean evalBool(EvalContext ctx) {
+        return E.asBoolean(subEval(ctx, true));
     }
 
     /**
@@ -109,13 +108,23 @@
     }
 
     /**
-     * The returns a static scope analysis of a subtree that doesn't
-     * depend on the enclosing context.
+     * Append the sequence of operations representated by this node to the
+     * argument.
+     * @param accum
      */
-    public final StaticScope staticScope() {
-        if (myOptStaticScope == null) {
-            myOptStaticScope = computeStaticScope();
-        }
-        return myOptStaticScope;
+    protected void appendTo(List accum) {
+        accum.add(this);
     }
+
+    /**
+     * Recursively append all the supplied nodes to accum.
+     * @param accum the List to accumulate the results into.
+     * @param all the EExprs to accumulate.
+     */
+    static protected void appendAllTo(List accum, EExpr[] all) {
+     	for (int i = 0, max = all.length; i < max; i++) {
+            all[i].appendTo(accum);
+    	}
+    }
+
 }



1.24      +11 -6     e/src/jsrc/org/erights/e/elang/evm/EImpl.java

Index: EImpl.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/EImpl.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- EImpl.java	2001/09/06 09:55:44	1.23
+++ EImpl.java	2001/11/09 01:17:20	1.24
@@ -20,7 +20,8 @@
 */
 
 import org.erights.e.elang.interp.ProtocolDesc;
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
+import org.erights.e.elang.scope.OuterScope;
 import org.erights.e.elib.base.Callable;
 import org.erights.e.elib.base.MessageDesc;
 import org.erights.e.elib.base.MethodNode;
@@ -40,14 +41,16 @@
  */
 public abstract class EImpl implements Callable {
 
-    /*package*/ Scope myScope;
+    /*package*/ Object[] myFields;
+    /*package*/ OuterScope myOuters;
     /*package*/ Script myScript;
 
     /**
      *
      */
-    /*package*/ EImpl(Scope scope, Script script) {
-        myScope = scope;
+    /*package*/ EImpl(Object[] fields, OuterScope outers, Script script) {
+        myFields = fields;
+        myOuters = outers;
         myScript = script;
     }
 
@@ -92,7 +95,9 @@
     /**
      * All security rests on not making this more visible than "package"
      */
-    /*package*/ Scope scope() { return myScope; }
+    /*package*/ EvalContext newContext(int localCount) {
+        return EvalContext.make(localCount, myFields, myOuters);
+    }
 
     /**
      * XXX controversial whether this should be made public
@@ -108,7 +113,7 @@
         if (myScript instanceof VTable) {
             VTable vTable = (VTable)myScript;
             MethodNode meth = vTable.optMethod("printOn", 1);
-            if (meth != null && meth instanceof EMethod) {
+            if (meth != null && meth instanceof EMethodNode) {
                 //If E code overrides printOn/1, we should invoke
                 //E.toString(obj).
                 //The instanceOf check avoids infinite regress with the



1.9       +3 -3      e/src/jsrc/org/erights/e/elang/evm/EImplByProxy.java

Index: EImplByProxy.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/EImplByProxy.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- EImplByProxy.java	2001/04/13 08:08:34	1.8
+++ EImplByProxy.java	2001/11/09 01:17:20	1.9
@@ -19,10 +19,10 @@
 Contributor(s): ______________________________________.
 */
 import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.OuterScope;
 import org.erights.e.elib.base.Script;
 import org.erights.e.elib.serial.PassByProxy;
 
-
 /**
  * An EImpl that's PassByProxy
  *
@@ -33,7 +33,7 @@
     /**
      *
      */
-    public EImplByProxy(Scope scope, Script script) {
-        super(scope, script);
+    public EImplByProxy(Object[] fields, OuterScope outers, Script script) {
+        super(fields, outers, script);
     }
 }



1.6       +5 -2      e/src/jsrc/org/erights/e/elang/evm/EMeta.java

Index: EMeta.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/EMeta.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- EMeta.java	2001/09/07 05:49:20	1.5
+++ EMeta.java	2001/11/09 01:17:20	1.6
@@ -6,7 +6,9 @@
 
 import java.io.IOException;
 
+import java.io.IOException;
 
+
 /**
  * Gives meta-level access to the object it wraps (its subject).
  *
@@ -39,10 +41,11 @@
     }
 
     /**
-     *
+     * @deprecated
      */
     public Scope getScope() {
-        return ((EImpl)mySubject).myScope;
+        // TODO return ((EImpl)mySubject).myScope;
+        throw new RuntimeException("TODO unimplemented");
     }
 
     /**



1.14      +40 -52    e/src/jsrc/org/erights/e/elang/evm/EMethod.java

Index: EMethod.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/EMethod.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- EMethod.java	2001/09/07 05:49:20	1.13
+++ EMethod.java	2001/11/09 01:17:20	1.14
@@ -19,19 +19,18 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.develop.exception.ExceptionMgr;
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
-import org.erights.e.elib.base.MethodNode;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.E;
 import org.erights.e.elib.ref.Ref;
 import org.erights.e.elib.slot.ValueGuard;
 import org.erights.e.elib.tables.FlexList;
-import org.erights.e.elib.tables.FlexMap;
 
 import java.io.IOException;
 
+import java.io.IOException;
+
 
 /**
  * BNF: <docComment> "to" verb "(" patterns ")" "{" expr "}" <p>
@@ -41,16 +40,15 @@
  * @see org.erights.e.elib.prim.VTable
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public class EMethod extends MethodNode implements ENode {
-
-    private StaticScope myOptStaticScope = null;
+public class EMethod extends ENode {
 
     private String myDocComment;
     private String myVerb;
     private Pattern[] myPatterns;
     private EExpr myReturnGuard;
     private EExpr myBody;
-
+    private int myLocalCount= -1;
+    
     /**
      * The constructor interns the verb
      */
@@ -71,6 +69,28 @@
     }
 
     /**
+     * Create the EMethod with the number of locals to allocate to a stack frame.
+     * This method assumes the verb is interned.
+     */
+    public EMethod(String docComment,
+                   String verb, 
+                   Pattern[] patterns, 
+                   EExpr returnGuard,
+                   EExpr body,
+                   int localCount)
+    {
+        if (docComment == null) {
+            docComment = "Oops, sysopsis was null";
+        }
+        myDocComment = docComment;
+        myVerb = verb;
+        myPatterns = patterns;
+        myReturnGuard = returnGuard;
+        myBody = body;
+        myLocalCount = localCount;
+    }
+
+    /**
      *
      */
     public Object welcome(ETreeVisitor visitor) {
@@ -86,7 +106,7 @@
      * computeStaticScope() to do the actual computation, which is
      * then remembered.
      */
-    private StaticScope computeStaticScope() {
+    protected StaticScope computeStaticScope() {
         StaticScope result = StaticScope.EmptyScope;
         for (int i = 0; i < myPatterns.length; i++) {
             result = result.add(myPatterns[i].staticScope());
@@ -98,22 +118,16 @@
     /**
      *
      */
-    public Object execute(Object self, String aVerb, Object[] args) {
-        if (arity() != args.length
-            || (myVerb != aVerb && ! myVerb.equals(aVerb)) ) {
-
-            throw ExceptionMgr.asSafe(new NoSuchMethodException(aVerb + "/"
-                                                                + args.length));
-        }
-        Scope[] pov = ((EImpl)self).scope().sprout().newPov();
-        for (int i = 0; i < args.length; i++) {
-            pov[0] = myPatterns[i].testMatch(pov[0], args[i], null);
-        }
-        Object vg = myReturnGuard.subEval(pov, false);
-        ValueGuard valueGuard = (ValueGuard)E.as(vg, ValueGuard.class);
-
-        //XXX onlyFlag should be true if myReturnGuard == e`void`
-        Object result = myBody.subEval(pov, false);
+    public Object execute(Object self, Object[] args) {
+        EvalContext ctx = ((EImpl) self).newContext(myLocalCount);
+        for (int i = 0, max = args.length; i < max; i++) {
+            myPatterns[i].testMatch(ctx, args[i], null);
+        }
+        Object vg = myReturnGuard.subEval(ctx, true);
+        ValueGuard valueGuard = (ValueGuard) E.as(vg, ValueGuard.class);
+        
+        //XXX forValue should be false if myReturnGuard == e`void`
+        Object result = myBody.subEval(ctx, true); 
         return valueGuard.coerce(result, null);
     }
 
@@ -147,23 +161,8 @@
      *
      */
     public String verb() { return myVerb; }
-
-    /**
-     *
-     */
-    public String optTypedVerb() { return null; }
-
-    /**
-     *
-     */
-    public int arity() { return myPatterns.length; }
 
-    /**
-     * Do nothing
-     */
-    public void addJavaMemberNodesToMap(FlexMap map) {}
-
-    /**
+   /**
      *
      */
     public Pattern[] patterns() { return myPatterns; }
@@ -191,16 +190,5 @@
         myReturnGuard.subPrintOn(out, PR_ORDER);
         out.print(" ");
         myBody.printAsBlockOn(out);
-    }
-
-    /**
-     * The returns a static scope analysis of a subtree that doesn't
-     * depend on the enclosing context.
-     */
-    public final StaticScope staticScope() {
-        if (myOptStaticScope == null) {
-            myOptStaticScope = computeStaticScope();
-        }
-        return myOptStaticScope;
     }
 }



1.6       +49 -10    e/src/jsrc/org/erights/e/elang/evm/ENode.java

Index: ENode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/ENode.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ENode.java	2001/09/06 09:55:44	1.5
+++ ENode.java	2001/11/09 01:17:20	1.6
@@ -21,17 +21,22 @@
 Contributor(s): ______________________________________.
 */
 
+import org.erights.e.elang.scope.ScopeMap;
 import org.erights.e.elang.visitors.ETreeVisitor;
-import org.erights.e.elib.base.SourceSpan;
+import org.erights.e.elib.base.ParseNode;
+import org.erights.e.elib.util.AlreadyDefinedException;
 
-
 /**
  * Those ParseNodes that--after expansion--define the kernel
  * nodes evaluated by the E Virtual Machine.
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public interface ENode {
+public abstract class ENode extends ParseNode implements Cloneable {
+
+    private StaticScope myOptStaticScope;
+
+    private ScopeMap myOptScopeMap;
 
     /**
      * A node welcomes a visitor by asking the visitor to visit it in
@@ -43,21 +48,55 @@
      * starting point for this pattern is the "Visitor" pattern from
      * the "Design Patterns" book.
      */
-    Object welcome(ETreeVisitor visitor);
+    public abstract Object welcome(ETreeVisitor visitor);
 
     /**
-     * The returns a static scope analysis of a subtree that doesn't
+     * Return a static scope analysis of a subtree that doesn't
      * depend on the enclosing context.
      */
-    StaticScope staticScope();
+    public final StaticScope staticScope() {
+        if (myOptStaticScope == null) {
+            myOptStaticScope = computeStaticScope();
+        }
+        return myOptStaticScope;
+    }
 
     /**
-     * kludge: Mirrors ParseNode
+     * When staticScope() is first requested on a given node, it calls
+     * computeStaticScope() to do the actual computation, which is
+     * then remembered.
      */
-    SourceSpan optSource();
+    /*package*/ abstract StaticScope computeStaticScope();
 
     /**
-     * kludge: Mirrors ParseNode
+      * Make a copy.
+      */
+    public ENode copy() {
+        try {
+            ENode node = (ENode) clone();
+            node.cleanCopy();
+            return node;
+        } catch (CloneNotSupportedException ex) {
+            throw new Error("Clone broken");
+        }
+    }
+
+    protected void cleanCopy() {
+        super.cleanCopy();
+        myOptScopeMap = null;
+    }
+
+    /**
+     *
      */
-    void defineSource(SourceSpan source);
+    public final ScopeMap optScopeMap() {
+        return myOptScopeMap;
+    }
+
+    public final void setScopeMap(ScopeMap map) {
+        if (null != myOptScopeMap) {
+            throw new AlreadyDefinedException("The scope map for a node may not be reassigned");
+        }
+        myOptScopeMap = map;
+    }
 }



1.11      +15 -23    e/src/jsrc/org/erights/e/elang/evm/EScript.java

Index: EScript.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/EScript.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- EScript.java	2001/09/07 05:49:20	1.10
+++ EScript.java	2001/11/09 01:17:20	1.11
@@ -19,7 +19,6 @@
 Contributor(s): ______________________________________.
 */
 import org.erights.e.elang.visitors.ETreeVisitor;
-import org.erights.e.elib.base.ParseNode;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
 import org.erights.e.elib.tables.ConstList;
@@ -27,6 +26,8 @@
 
 import java.io.IOException;
 
+import java.io.IOException;
+
 /**
  * <pre>
  * BNF: script ::= "{" method* matcher? "}" ("meta" script)?
@@ -39,17 +40,15 @@
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public class EScript extends ParseNode implements ENode {
+public class EScript extends ENode {
 
-    /*package*/ EMethod[] myOptMethods;
+    /*package*/ EMethodNode[] myOptMethods;
     private Matcher myOptMatcher;
 
-    private StaticScope myOptStaticScope = null;
-
     /**
      *
      */
-    public EScript(EMethod[] optMethods, Matcher optMatcher) {
+    public EScript(EMethodNode[] optMethods, Matcher optMatcher) {
         if (optMethods == null && optMatcher == null) {
             throw new RuntimeException(
             "At least one of optMethods or optMatcher must not be null");
@@ -79,11 +78,11 @@
     /**
      *
      */
-    /*package*/ StaticScope computeStaticScope() {
+    protected StaticScope computeStaticScope() {
         StaticScope result = StaticScope.EmptyScope;
         if (myOptMethods != null) {
-            for (int i = 0; i < myOptMethods.length; i++) {
-                result = result.add(myOptMethods[i].staticScope().hide());
+            for (int i = 0, max = myOptMethods.length; i < max; i++) {
+                result = result.add(myOptMethods[i].method().staticScope().hide());
             }
         }
         if (myOptMatcher != null) {
@@ -93,17 +92,6 @@
     }
 
     /**
-     * The returns a static scope analysis of a subtree that doesn't
-     * depend on the enclosing context.
-     */
-    public final StaticScope staticScope() {
-        if (myOptStaticScope == null) {
-            myOptStaticScope = computeStaticScope();
-        }
-        return myOptStaticScope;
-    }
-
-    /**
      *
      */
     public boolean matchBind(Object[] args,
@@ -122,8 +110,12 @@
             return false;
         }
         if (myOptMethods != null) {
-            if (! matchBind(myOptMethods, args, other.myOptMethods, bindings)) {
-                return false;
+            for (int i = 0, max = myOptMethods.length; i < max; i++) {
+                EMethod me = myOptMethods[i].method();
+                EMethod him = other.myOptMethods[i].method();
+                if (! matchBind(me, args, him, bindings)) {
+                    return false;
+                }
             }
         }
         return matchBind(myOptMatcher, args, other.myOptMatcher, bindings);
@@ -141,7 +133,7 @@
             out.print(" {");
             TextWriter sub = out.indent();
             for (int i = 0; i < myOptMethods.length; i++) {
-                myOptMethods[i].lnPrintOn(sub, PR_PRIM);
+                myOptMethods[i].method().lnPrintOn(sub, PR_PRIM);
             }
             if (myOptMatcher != null) {
                 myOptMatcher.lnPrintOn(sub, PR_PRIM);



1.25      +5 -5      e/src/jsrc/org/erights/e/elang/evm/EscapeExpr.java

Index: EscapeExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/EscapeExpr.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- EscapeExpr.java	2001/09/07 05:49:20	1.24
+++ EscapeExpr.java	2001/11/09 01:17:20	1.25
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.base.Ejector;
 import org.erights.e.elib.eio.TextWriter;
@@ -74,12 +74,12 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
         Ejector ejector = new Ejector();
-        Scope subPov[] = pov[0].sprout().newPov();
-        subPov[0] = myExitPatt.testMatch(subPov[0], ejector, null);
+        // NOTE should ejector be the specimen or the ejector? <comment>
+        myExitPatt.testMatch(ctx, ejector, null);
         try {
-            return myRValue.subEval(subPov, onlyFlag);
+            return myRValue.subEval(ctx, forValue);
         } catch (Throwable t) {
             return ejector.result(t);
         } finally {



1.10      +2 -2      e/src/jsrc/org/erights/e/elang/evm/Evaluator.java

Index: Evaluator.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/Evaluator.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Evaluator.java	2001/09/06 09:55:44	1.9
+++ Evaluator.java	2001/11/09 01:17:20	1.10
@@ -77,11 +77,11 @@
  *
  * In one crucial way, the Evaluator is less general than the notion
  * of evaluation defined by Kernel-E: To accomodate remote execution,
- * bindingsIn and bindingsOut must represent only to final variables,
+ * bindingsIn and bindingsOut must represent only final variables,
  * since they are a ConstMap mapping these names to values, rather
  * than settable locations.  While this difference is visible to the
  * Kernel-E programmer, it can be made largely invisible to the E
- * programmer.  Except for variable recognized to fall into some
+ * programmer.  Except for variables recognized to fall into some
  * special cases, the Deslotifying compilation phase transforms,
  * for example, the variable "foo" into corresponding final variable
  * "foo__Slot", bound to an explicit Slot object holding the value of



1.10      +21 -88    e/src/jsrc/org/erights/e/elang/evm/FinalPattern.java

Index: FinalPattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/FinalPattern.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- FinalPattern.java	2001/09/07 05:49:20	1.9
+++ FinalPattern.java	2001/11/09 01:17:20	1.10
@@ -19,8 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.interp.ScopeSetup;
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.E;
@@ -52,23 +51,17 @@
  * user-level language, but the kernel-level language (ie, the parse node
  * FinalPattern) imposes a well-formedness criterea that allows us to
  * evaluate in the wrong order without effect.  A circular user-level
- * FinalPattern will also be statically rejected <p>
+ * final-pattern must be translated into a well-formed kernel-level
+ * FinalPattern. <p>
  *
  * @see org.erights.e.elang.evm.DefineExpr
  * @see org.erights.e.elang.evm.VarPattern
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public class FinalPattern extends Pattern {
+public class FinalPattern extends NounPattern {
 
-    /**
-     * A set of all the variable names that may not be shadowed (ie,
-     * redefined)
-     */
-    static public final ConstMap NonShadowable
-        = ScopeSetup.universal().asMap();
-
-    private String myVarName;
-    private EExpr myValueGuardExpr;
+    private NounExpr myNoun;
+    private EExpr myValueGuard;
 
     /**
      * If 'varName' would shadow a non-shadowable, throw a (XXX to be
@@ -77,105 +70,45 @@
      * If the FinalPattern would not be well-formed, throw a (XXX to be
      * defined) exception instead.  <p>
      */
-    public FinalPattern(String varName, EExpr valueGuardExpr) {
-        myVarName = varName;
-        myValueGuardExpr = valueGuardExpr;
-        if (NonShadowable.maps(myVarName)) {
-            throw new RuntimeException("can't redefine " + myVarName);
-        }
-        ensureWellFormed();
+    public FinalPattern(String varName, NounExpr noun, EExpr guardExpr) {
+        super(varName);
+        myNoun = noun;
+        myValueGuard = guardExpr;
+        ensureWellFormed(myValueGuard);
     }
 
-    /**
-     *
-     */
-    private void ensureWellFormed() {
-        StaticScope smScope = myValueGuardExpr.staticScope();
-        if (smScope.namesUsed().maps(myVarName)) {
-            throw new RuntimeException
-                ("kernel FinalPattern cycle not allowed: " + myVarName);
-        }
-        if (smScope.namesOut().maps(myVarName)) {
-            throw new RuntimeException
-                ("kernel FinalPattern shadow not allowed: " + myVarName);
-        }
+    public FinalPattern(String varName, EExpr guardExpr) {
+        this(varName, new NounExpr(varName), guardExpr);
     }
 
     /**
      *
      */
     public Object welcome(ETreeVisitor visitor) {
-        return visitor.visitFinalPattern(myVarName, myValueGuardExpr);
-    }
-
-    /**
-     *
-     */
-    /*package*/ StaticScope computeStaticScope() {
-        FlexMap namesOut = FlexMap.fromTypes(String.class, Void.class);
-        namesOut.put(myVarName, null);
-        StaticScope result = new StaticScope(StaticScope.EmptyMap,
-                                             StaticScope.EmptyMap,
-                                             false,
-                                             namesOut.snapshot());
-        result = result.add(myValueGuardExpr.staticScope());
-        return result;
+        return visitor.visitFinalPattern(optName(), myValueGuard);
     }
 
-    /**
-     *
-     */
-    public boolean matchBind(Object[] args,
-                             Object specimen,
-                             FlexList bindings)
-    {
-        FinalPattern other;
-        try {
-            other = (FinalPattern)Ref.resolution(specimen);
-        } catch (ClassCastException cce) {
-            //using a try/catch since success is typical and we have
-            //to pay for the test in the cast anyway
-            return false;
-        }
-        return (myVarName.equals(other.myVarName)
-                && matchBind(myValueGuardExpr,
-                             args,
-                             other.myValueGuardExpr,
-                             bindings));
+    public NounExpr getNoun() {
+        return myNoun;
     }
-    /**
-     * A FinalPattern will never return null for this.  It is named
-     * 'optName' because it is polymorphic with IgnorePattern
-     */
-    public String optName()         { return myVarName; }
 
     /**
      *
      */
-    public EExpr valueGuardExpr() { return myValueGuardExpr; }
-
-    /**
-     *
-     */
-    public void subPrintOn(TextWriter out, int priority) throws IOException {
-        out.print(myVarName, " :");
-        myValueGuardExpr.subPrintOn(out, PR_ORDER);
-    }
+    protected EExpr guardExpr() { return myValueGuard; }
 
     /**
      *
      */
-    /*package*/ Scope testMatch(Scope scope,
+    /*package*/ void testMatch(EvalContext ctx,
                                 Object specimen,
                                 OneArgFunc optEjector)
     {
-        Scope[] pov = scope.newPov();
         //Because of the well-formedness criterea, we may safely evaluate
         //this in the wrong order
-        Object sg = myValueGuardExpr.subEval(pov, false);
-        ValueGuard valueGuard = (ValueGuard)E.as(sg, ValueGuard.class);
+        Object sg = myValueGuard.subEval(ctx, true);
+        ValueGuard valueGuard = (ValueGuard) E.as(sg, ValueGuard.class);
         Object value = valueGuard.coerce(specimen, optEjector);
-        pov[0] = pov[0].bindFinal(myVarName, value);
-        return pov[0];
+        myNoun.initFinal(ctx, value);
     }
 }



1.14      +4 -5      e/src/jsrc/org/erights/e/elang/evm/FinallyExpr.java

Index: FinallyExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/FinallyExpr.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- FinallyExpr.java	2001/09/07 05:49:20	1.13
+++ FinallyExpr.java	2001/11/09 01:17:20	1.14
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
@@ -78,12 +78,11 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
         try {
-            return myAttempt.subEval(pov[0].sprout().newPov(), onlyFlag);
-
+            return myAttempt.subEval(ctx, forValue);
         } finally {
-            myUnwinder.subEval(pov[0].sprout().newPov(), true);
+            myUnwinder.subEval(ctx, false);
         }
     }
 



1.22      +3 -3      e/src/jsrc/org/erights/e/elang/evm/HideExpr.java

Index: HideExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/HideExpr.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- HideExpr.java	2001/09/07 05:49:20	1.21
+++ HideExpr.java	2001/11/09 01:17:20	1.22
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
@@ -68,8 +68,8 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
-        return myBlock.subEval(pov[0].sprout().newPov(), onlyFlag);
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
+        return myBlock.subEval(ctx, forValue);
     }
 
     /**



1.23      +6 -6      e/src/jsrc/org/erights/e/elang/evm/IfExpr.java

Index: IfExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/IfExpr.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- IfExpr.java	2001/09/07 05:49:20	1.22
+++ IfExpr.java	2001/11/09 01:17:20	1.23
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
@@ -28,6 +28,7 @@
 import java.io.IOException;
 
 
+
 /**
  * BNF: "if" "(" cond-expr ")" "{" then-expr "}" "else" "{" else-expr "}" <p>
  *
@@ -78,16 +79,15 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
-        Scope[] subPov = pov[0].sprout().newPov();
-        if (myTest.evalBool(subPov)) {
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
+        if (myTest.evalBool(ctx)) {
             //the then part executes in a scope containing bindings
             //from the conditional
-            return myThen.subEval(subPov, onlyFlag);
+            return myThen.subEval(ctx, forValue);
         } else {
             //else is evaluated in a new scope with no bindings from
             //the conditional
-            return myElse.subEval(pov[0].sprout().newPov(), onlyFlag);
+            return myElse.subEval(ctx, forValue);
         }
     }
 



1.11      +4 -3      e/src/jsrc/org/erights/e/elang/evm/IgnorePattern.java

Index: IgnorePattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/IgnorePattern.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- IgnorePattern.java	2001/09/07 05:49:20	1.10
+++ IgnorePattern.java	2001/11/09 01:17:20	1.11
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
@@ -91,10 +91,11 @@
     /**
      *
      */
-    /*package*/ Scope testMatch(Scope scope,
+    /*package*/ void testMatch(EvalContext ctx,
                                 Object specimen,
                                 OneArgFunc optEjector)
     {
-        return scope;
+        return;
     }
+
 }



1.13      +5 -7      e/src/jsrc/org/erights/e/elang/evm/ListPattern.java

Index: ListPattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/ListPattern.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- ListPattern.java	2001/09/07 05:49:20	1.12
+++ ListPattern.java	2001/11/09 01:17:20	1.13
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.Thrower;
@@ -96,10 +96,11 @@
     /**
      *
      */
-    /*package*/ Scope testMatch(Scope scope,
+    /*package*/ void testMatch(EvalContext ctx,
                                 Object specimen,
                                 OneArgFunc optEjector)
     {
+        // TODO this looks a lot like the method in CdrPattern
         //XXX should really coerce to a list here
         specimen = Ref.resolution(specimen);
         if (specimen == null) {
@@ -124,12 +125,9 @@
                                   " size list doesn't match a " +
                                   mySubs.length + " size list pattern");
         }
-        for (int i = 0; i < mySubs.length; i++) {
-            scope = (Scope)mySubs[i].testMatch(scope,
-                                               list.get(i),
-                                               optEjector);
+        for (int i = 0, max = mySubs.length; i < max; i++) {
+            mySubs[i].testMatch(ctx, list.get(i), optEjector);
         }
-        return scope;
     }
 
     /**



1.22      +2 -2      e/src/jsrc/org/erights/e/elang/evm/LiteralExpr.java

Index: LiteralExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/LiteralExpr.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- LiteralExpr.java	2001/09/07 05:49:20	1.21
+++ LiteralExpr.java	2001/11/09 01:17:20	1.22
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 import org.erights.e.develop.format.StringHelper;
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
@@ -64,7 +64,7 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
         return myValue;
     }
 



1.27      +35 -5     e/src/jsrc/org/erights/e/elang/evm/MatchBindExpr.java

Index: MatchBindExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/MatchBindExpr.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- MatchBindExpr.java	2001/09/07 05:49:20	1.26
+++ MatchBindExpr.java	2001/11/09 01:17:20	1.27
@@ -19,8 +19,9 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
+import org.erights.e.elib.base.Ejector;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
 import org.erights.e.elib.tables.FlexList;
@@ -28,6 +29,7 @@
 import java.io.IOException;
 
 
+
 /**
  * BNF: eExpr "=~" pattern <p>
  *
@@ -39,6 +41,7 @@
 
     private EExpr mySpecimen;
     private Pattern myPattern;
+    private NounExpr[] myOptBound;
 
     /**
      *
@@ -48,6 +51,12 @@
         myPattern = pattern;
     }
 
+    public MatchBindExpr(EExpr specimen, Pattern pattern, NounExpr[] bound) {
+        mySpecimen = specimen;
+        myPattern = pattern;
+        myOptBound = bound;
+    }
+
     /**
      *
      */
@@ -65,14 +74,35 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
-        Object left = mySpecimen.subEval(pov, false);
-        if (myPattern.matches(pov, left)) {
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
+        Ejector ej = new Ejector();
+        Object left = mySpecimen.subEval(ctx, true);
+        try {
+            myPattern.testMatch(ctx, left, ej);
             return Boolean.TRUE;
-        } else {
+        } catch (Throwable t) {
+            breakAll(ctx, (Throwable) ej.result(t));
             return Boolean.FALSE;
+        } finally {
+            ej.disable();
         }
     }
+
+    private void breakAll(EvalContext ctx, Throwable reason) {
+        Object ruined = Ref.broken(reason);
+        for (int i = 0, max = myOptBound.length; i < max; i++) {
+            // this should only allocated the final slot once when the nouns
+            // are vars.
+            myOptBound[i].initFinal(ctx, ruined);
+        }
+    }
+
+    /**
+     * Like testMatch(), except it must produce a
+     * successor scope on failure as well.  On failure, the successor
+     * scope contains broken bindings for all names exported by this
+     * pattern.
+     */
 
     /**
      *



1.10      +18 -22    e/src/jsrc/org/erights/e/elang/evm/Matcher.java

Index: Matcher.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/Matcher.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Matcher.java	2001/09/07 05:49:20	1.9
+++ Matcher.java	2001/11/09 01:17:20	1.10
@@ -18,9 +18,8 @@
 
 Contributor(s): ______________________________________.
 */
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
-import org.erights.e.elib.base.ParseNode;
 import org.erights.e.elib.base.Script;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.base.TypeDesc;
@@ -42,14 +41,13 @@
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public class Matcher extends ParseNode implements Script, ENode {
+public class Matcher extends ENode implements Script {
 
     static private final Object[] NO_ARGS = {};
 
-    private StaticScope myOptStaticScope = null;
-
     private Pattern myPattern;
     private EExpr myBody;
+    private int myLocalCount = -1;
 
     /**
      *
@@ -62,6 +60,15 @@
     /**
      *
      */
+    public Matcher(Pattern pattern, EExpr body, int localCount) {
+        myPattern = pattern;
+        myBody = body;
+        myLocalCount = localCount;
+    }
+
+    /**
+     *
+     */
     public Object welcome(ETreeVisitor visitor) {
         return visitor.visitMatcher(myPattern, myBody);
     }
@@ -81,7 +88,7 @@
      * computeStaticScope() to do the actual computation, which is
      * then remembered.
      */
-    private StaticScope computeStaticScope() {
+    protected StaticScope computeStaticScope() {
         StaticScope result = myPattern.staticScope();
         result = result.add(myBody.staticScope()).hide();
         return result;
@@ -92,13 +99,13 @@
      */
     public Object execute(Object self, String verb, Object[] args) {
         Object[] message = { verb, ConstList.fromArray(args) };
-        Scope[] pov = ((EImpl)self).scope().sprout().newPov();
+        EvalContext ctx = ((EImpl) self).newContext(myLocalCount);
         //it *must* bind when it's directly executed, as opposed to when
         //it's in a switch
-        pov[0] = myPattern.testMatch(pov[0],
-                                     ConstList.fromArray(message),
-                                     null);
-        return myBody.subEval(pov, false);
+        myPattern.testMatch(ctx,
+                            ConstList.fromArray(message),
+                            null);
+        return myBody.subEval(ctx, true);
     }
 
     /**
@@ -148,16 +155,5 @@
         Object[] args = { verb, BigInteger.valueOf(arity) };
         result = execute(self, "respondsTo", args);
         return ((Boolean)result).booleanValue();
-    }
-
-    /**
-     * The returns a static scope analysis of a subtree that doesn't
-     * depend on the enclosing context.
-     */
-    public final StaticScope staticScope() {
-        if (myOptStaticScope == null) {
-            myOptStaticScope = computeStaticScope();
-        }
-        return myOptStaticScope;
     }
 }



1.10      +3 -3      e/src/jsrc/org/erights/e/elang/evm/MetaExpr.java

Index: MetaExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/MetaExpr.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- MetaExpr.java	2001/09/07 05:49:20	1.9
+++ MetaExpr.java	2001/11/09 01:17:20	1.10
@@ -1,6 +1,6 @@
 package org.erights.e.elang.evm;
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
@@ -45,8 +45,8 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag)  {
-        return new EMeta(myNoun.subEval(pov, false));
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue)  {
+        return forValue ? new EMeta(myNoun.subEval(ctx, true)) : null ;
     }
 
     /**



1.25      +84 -11    e/src/jsrc/org/erights/e/elang/evm/NounExpr.java

Index: NounExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/NounExpr.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- NounExpr.java	2001/09/07 05:49:20	1.24
+++ NounExpr.java	2001/11/09 01:17:20	1.25
@@ -19,15 +19,18 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
+import org.erights.e.elib.slot.FinalSlotMaker;
+import org.erights.e.elib.slot.Slot;
 import org.erights.e.elib.tables.FlexList;
 import org.erights.e.elib.tables.FlexMap;
 
 import java.io.IOException;
 
+import java.io.IOException;
 
 /**
  * BNF: varName <p>
@@ -53,27 +56,46 @@
     /**
      *
      */
+    public boolean isFinal() {
+        return true;
+    }
+
+    /**
+     *
+     */
+    public boolean isOuter() {
+        return false;
+    }
+
+     /**
+     *
+     */
     public Object welcome(ETreeVisitor visitor) {
         return visitor.visitNounExpr(myName);
     }
 
-    /**
+   /**
      *
      */
     /*package*/ StaticScope computeStaticScope() {
         FlexMap namesRead = FlexMap.fromTypes(String.class, Void.class);
         namesRead.put(myName, null);
-        return new StaticScope(namesRead.snapshot(),
-                               StaticScope.EmptyMap,
-                               false,
-                               StaticScope.EmptyMap);
+        return StaticScope.scopeRead(namesRead.snapshot());
     }
 
     /**
-     *
+     * Default implementation of noun eval in terms of its slot.
+     */
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
+        return getSlot(ctx).getValue();
+    }
+
+    /**
+     * Get the value in the EvalContext.
+     * TODO should this be public?
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
-        return pov[0].get(myName);
+    public Object getIn(EvalContext ctx) {
+        return subEval(ctx, true);
     }
 
     /**
@@ -85,7 +107,7 @@
     {
         NounExpr other;
         try {
-            other = (NounExpr)Ref.resolution(specimen);
+            other = (NounExpr) Ref.resolution(specimen);
         } catch (ClassCastException cce) {
             //using a try/catch since success is typical and we have
             //to pay for the test in the cast anyway
@@ -97,7 +119,7 @@
     /**
      *
      */
-    public String name()             { return myName; }
+    public String name() { return myName; }
 
     /**
      *
@@ -105,4 +127,55 @@
     public void subPrintOn(TextWriter out, int priority) throws IOException {
         out.print(myName);
     }
+
+    /**
+     * Return the kind of object that should be stored in a frame, assuming
+     * an accessor of the same type as the receiver.
+     * Default implementation of getRespresentation in terms of the slot.
+     * Used for transferring the contents of the slot into a frame field
+     * from an outer scope.
+     */
+    public Object getRepresentation(EvalContext ctx) {
+        return getSlot(ctx);
+    }
+
+    /**
+     * Return a slot object from the EvalContext for the noun designated by
+     * the receiver.
+     */
+    public Slot getSlot(EvalContext ctx) {
+        throw new RuntimeException("This node should have been transformed");
+    }
+
+    /**
+     * Return a noun that could access the representation of the receiver if it
+     * were at in a frame at the given index.  This is used to maintain final/var
+     * distinctions as slots are copied into frames.
+     */
+    public NounExpr asFieldAt(int index) {
+        throw new RuntimeException("This node should have been transformed");
+    }
+
+    /**
+     * Default implementation of assign in terms of the slot.  Note that this raises
+     * the correct exception if the slot is a final slot.
+     */
+    public void assign(EvalContext ctx, Object value) {
+        getSlot(ctx).setValue(value);
+    }
+
+    /**
+     * Initialize a final variable's value when it first comes into scope.
+     */
+    public void initFinal(EvalContext ctx, Object value) {
+        initSlot(ctx, FinalSlotMaker.THE_ONE.makeSlot(value, null));
+    }
+
+    /**
+     * Initialize a slot variable when it first comes into scope.
+     */
+    public void initSlot(EvalContext ctx, Slot slot) {
+        throw new RuntimeException("This node should have been transformed");
+    }
+
 }



1.36      +44 -5     e/src/jsrc/org/erights/e/elang/evm/ObjectExpr.java

Index: ObjectExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/ObjectExpr.java,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- ObjectExpr.java	2001/09/07 05:49:20	1.35
+++ ObjectExpr.java	2001/11/09 01:17:20	1.36
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.MirandaMethods;
@@ -50,6 +50,7 @@
     private String myOptFQN;
     private NounExpr[] myAuditors;
     private EScript myEScript;
+    private NounExpr[] myOptFieldInits;
 
     private VTable myOptVtableCache = null;
 
@@ -73,6 +74,25 @@
     /**
      *
      */
+    public ObjectExpr(String docComment,
+                      String optFQN,
+                      NounExpr[] auditors,
+                      EScript eScript,
+                      NounExpr[] fieldNouns)
+    {
+        if (docComment == null) {
+            docComment = "Oops, docComment was null";
+        }
+        myDocComment = docComment;
+        myOptFQN = optFQN;
+        myAuditors = auditors;
+        myEScript = eScript;
+        myOptFieldInits = fieldNouns;
+    }
+
+    /**
+     *
+     */
     public Object welcome(ETreeVisitor visitor) {
         return visitor.visitObjectExpr(myDocComment,
                                        myOptFQN,
@@ -80,6 +100,17 @@
                                        myEScript);
     }
 
+
+    /**
+     * Return the nouns used to initialize instance
+     * fields from the outer scope.  <p>
+     *
+     * Will be non-null after the appropriate compilation transformation.
+     */
+    /*package*/ NounExpr[] optFieldNouns() {
+        return myOptFieldInits;
+    }
+
     /**
      * XXX doesn't do anything with Auditors yet.
      */
@@ -90,8 +121,16 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
-        return new EImplByProxy(pov[0], vTable());
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
+        if (! forValue) {
+            return null;
+        }
+        int max = myOptFieldInits.length;
+        Object[] fields = new Object[max];
+        for (int i = 0; i < max; i++) {
+            fields[i] = myOptFieldInits[i].getRepresentation(ctx);
+        }
+        return new EImplByProxy(fields, ctx.outers(), vTable());
     }
 
 
@@ -175,11 +214,11 @@
         if (myOptVtableCache == null) {
             myOptVtableCache = new VTable(optName(),
                                           myEScript.optMatcher());
-            EMethod[] optMeths = myEScript.myOptMethods;
+            EMethodNode[] optMeths = myEScript.myOptMethods;
             if (optMeths != null) {
                 SugarMethodNode.defineMembers(myOptVtableCache,
                                               MirandaMethods.class);
-                for (int i = 0; i < optMeths.length; i++) {
+                for (int i = 0, max = optMeths.length; i < max; i++) {
                     myOptVtableCache.addMethod(optMeths[i],
                                                ConstMap.EmptyMap);
                 }



1.28      +5 -53     e/src/jsrc/org/erights/e/elang/evm/Pattern.java

Index: Pattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/Pattern.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- Pattern.java	2001/10/01 08:31:04	1.27
+++ Pattern.java	2001/11/09 01:17:20	1.28
@@ -19,13 +19,10 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.SubstVisitor;
-import org.erights.e.elib.base.Ejector;
-import org.erights.e.elib.base.ParseNode;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.util.OneArgFunc;
-import org.erights.e.elib.prim.E;
 
 import java.io.IOException;
 
@@ -38,10 +35,8 @@
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public abstract class Pattern extends ParseNode implements ENode {
+public abstract class Pattern extends ENode {
 
-    private StaticScope myOptStaticScope = null;
-
     /**
      *
      */
@@ -64,56 +59,13 @@
         return visitor.xformPattern(this);
     }
 
-    /**
-     * Like testMatch(), except it side effects pov[0] in place
-     * rather than returning the new Scope, and it must produce a
-     * successor scope on failure as well.  On failure, the successor
-     * scope contains broken bindings for all names exported by this
-     * pattern.
-     */
-    /*package*/ boolean matches(Scope[] pov, Object specimen) {
-        Scope after = null;
-        Ejector ej = new Ejector();
-        try {
-            after = testMatch(pov[0], specimen, ej);
-        } catch (Throwable t) {
-            RuntimeException reason = E.asRTE(ej.result(t));
-            pov[0] = pov[0].brokenBindings(staticScope().namesOut(),
-                                           reason);
-            return false;
-        } finally {
-            ej.disable();
-        }
-        pov[0] = after;
-        return true;
-    }
-
     /**
-     * If this pattern matches the specimen, return the resulting
-     * scope (containing the resulting bindings).  Otherwise report the
-     * reason why not according to optEjector.
+     * If this pattern matches the specimen, add mathing bindings to the scope
+     * Otherwise report the reason why not according to optEjector.
      */
-    /*package*/ abstract Scope testMatch(Scope scope,
+    /*package*/ abstract void testMatch(EvalContext ctx,
                                          Object specimen,
                                          OneArgFunc optEjector);
-
-    /**
-     * When staticScope() is first requested on a given node, it calls
-     * computeStaticScope() to do the actual computation, which is
-     * then remembered.
-     */
-    /*package*/ abstract StaticScope computeStaticScope();
-
-    /**
-     * This returns a static scope analysis of a subtree that doesn't
-     * depend on the enclosing context.
-     */
-    public final StaticScope staticScope() {
-        if (myOptStaticScope == null) {
-            myOptStaticScope = computeStaticScope();
-        }
-        return myOptStaticScope;
-    }
 
     /**
      * If this pattern is the binding occurence of a name, and it would bind



1.21      +3 -2      e/src/jsrc/org/erights/e/elang/evm/QuasiLiteralExpr.java

Index: QuasiLiteralExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/QuasiLiteralExpr.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- QuasiLiteralExpr.java	2001/09/07 05:49:20	1.20
+++ QuasiLiteralExpr.java	2001/11/09 01:17:20	1.21
@@ -18,7 +18,7 @@
 
 Contributor(s): ______________________________________.
 */
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.quasi.IncompleteQuasiException;
@@ -27,6 +27,7 @@
 import java.io.IOException;
 
 
+
 /**
  * BNF: '$' '{' <number> '}' <p>
  *
@@ -66,7 +67,7 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
         throw new IncompleteQuasiException
           ("Can't evaluate programs that still contain bare \"$\"s");
     }



1.11      +2 -2      e/src/jsrc/org/erights/e/elang/evm/QuasiLiteralPatt.java

Index: QuasiLiteralPatt.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/QuasiLiteralPatt.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- QuasiLiteralPatt.java	2001/09/07 05:49:20	1.10
+++ QuasiLiteralPatt.java	2001/11/09 01:17:20	1.11
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.quasi.IncompleteQuasiException;
@@ -68,7 +68,7 @@
      * throws a IncompleteQuasiException, rather than reporting a problem
      * according to optEjector
      */
-    /*package*/ Scope testMatch(Scope scope,
+    /*package*/ void testMatch(EvalContext ctx,
                                 Object specimen,
                                 OneArgFunc optEjector)
     {



1.22      +2 -2      e/src/jsrc/org/erights/e/elang/evm/QuasiPatternExpr.java

Index: QuasiPatternExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/QuasiPatternExpr.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- QuasiPatternExpr.java	2001/09/07 05:49:20	1.21
+++ QuasiPatternExpr.java	2001/11/09 01:17:20	1.22
@@ -18,7 +18,7 @@
 
 Contributor(s): ______________________________________.
 */
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.quasi.IncompleteQuasiException;
@@ -66,7 +66,7 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
         throw new IncompleteQuasiException
           ("Can't evaluate programs that contain bare \"@\"s");
     }



1.11      +2 -2      e/src/jsrc/org/erights/e/elang/evm/QuasiPatternPatt.java

Index: QuasiPatternPatt.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/QuasiPatternPatt.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- QuasiPatternPatt.java	2001/09/07 05:49:20	1.10
+++ QuasiPatternPatt.java	2001/11/09 01:17:20	1.11
@@ -18,7 +18,7 @@
 
 Contributor(s): ______________________________________.
 */
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.quasi.IncompleteQuasiException;
@@ -68,7 +68,7 @@
     /**
      * Throws an IncompleteQuasiException rather than indicating match failure
      */
-    /*package*/ Scope testMatch(Scope scope,
+    /*package*/ void testMatch(EvalContext ctx,
                                 Object specimen,
                                 OneArgFunc optEjector)
     {



1.21      +8 -6      e/src/jsrc/org/erights/e/elang/evm/ScopeExpr.java

Index: ScopeExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/ScopeExpr.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- ScopeExpr.java	2001/09/07 05:49:20	1.20
+++ ScopeExpr.java	2001/11/09 01:17:20	1.21
@@ -19,6 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.scope.Scope;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
@@ -28,6 +29,7 @@
 import java.io.IOException;
 
 
+
 /**
  * BNF: "meta scope" <p>
  *
@@ -52,17 +54,17 @@
      *
      */
     /*package*/ StaticScope computeStaticScope() {
-        return new StaticScope(StaticScope.EmptyMap,
-                               StaticScope.EmptyMap,
-                               true,
-                               StaticScope.EmptyMap);
+        return StaticScope.scopeMeta();
     }
 
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag)  {
-        return pov[0];
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue)  {
+        // NOTE this needs to strip the now-unreferenced content from
+        // the scope, possibly combining the scope with the current staticScope.
+        // TODO build a scope
+        return Scope.in(this, ctx);
     }
 
     /**



1.22      +8 -8      e/src/jsrc/org/erights/e/elang/evm/SendExpr.java

Index: SendExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/SendExpr.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- SendExpr.java	2001/09/07 05:49:20	1.21
+++ SendExpr.java	2001/11/09 01:17:20	1.22
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.E;
@@ -84,17 +84,17 @@
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
-        Object receiver = myRecipient.subEval(pov, false);
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
+        Object receiver = myRecipient.subEval(ctx, true);
         Object[] argVals = new Object[myArgs.length];
-        for (int i = 0; i < argVals.length; i++) {
-            argVals[i] = myArgs[i].subEval(pov, false);
+        for (int i = 0, max = argVals.length; i < max; i++) {
+            argVals[i] = myArgs[i].subEval(ctx, true);
         }
-        if (onlyFlag) {
+        if (forValue) {
+            return E.sendAll(receiver, myVerb, argVals);
+        } else {
             E.sendAllOnly(receiver, myVerb, argVals);
             return null;
-        } else {
-            return E.sendAll(receiver, myVerb, argVals);
         }
     }
 



1.9       +48 -20    e/src/jsrc/org/erights/e/elang/evm/SeqExpr.java

Index: SeqExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/SeqExpr.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- SeqExpr.java	2001/09/07 05:49:20	1.8
+++ SeqExpr.java	2001/11/09 01:17:20	1.9
@@ -19,15 +19,16 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
 import org.erights.e.elib.tables.FlexList;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
-
 /**
  * BNF: eExpr "\n" eExpr <p>
  *
@@ -36,38 +37,49 @@
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
 public class SeqExpr extends EExpr {
+
+    static private final EExpr[] EEXPR_PROTOTYPE = {};
 
-    private EExpr myFirst;
-    private EExpr mySecond;
+    private EExpr[] mySubs;
 
     /**
      *
      */
-    public SeqExpr(EExpr first, EExpr second) {
-        myFirst = first;
-        mySecond = second;
+    public SeqExpr(EExpr[] subs) {
+        List accum = new ArrayList(subs.length);
+        appendAllTo(accum, subs);
+        mySubs = (EExpr[]) accum.toArray(EEXPR_PROTOTYPE);
     }
 
     /**
      *
      */
     public Object welcome(ETreeVisitor visitor) {
-        return visitor.visitSeqExpr(myFirst, mySecond);
+        return visitor.visitSeqExpr(mySubs);
     }
 
     /**
      *
      */
     /*package*/ StaticScope computeStaticScope() {
-        return myFirst.staticScope().add(mySecond.staticScope());
+        StaticScope result = mySubs[0].staticScope();
+        // NOTE the loop begins at 1, not 0
+    	for (int i = 1, max = mySubs.length; i < max; i++) {
+            result = result.add(mySubs[i].staticScope());
+    	}
+    	return result;
     }
 
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
-        myFirst.subEval(pov, true);
-        return mySecond.subEval(pov, onlyFlag);
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
+    	// only compute a value for the last sub
+    	int last = mySubs.length - 1;
+    	for (int i = 0; i < last; i++) {
+            mySubs[i].subEval(ctx, false);
+    	}
+    	return mySubs[last].subEval(ctx, forValue);
     }
 
     /**
@@ -85,8 +97,17 @@
             //to pay for the test in the cast anyway
             return false;
         }
-        return (myFirst.matchBind(args, other.myFirst, bindings)
-                && mySecond.matchBind(args, other.mySecond, bindings));
+
+		EExpr[] subs = other.mySubs;
+		if (subs.length != mySubs.length) {
+			return false;
+		}
+    	for (int i = 0, max = mySubs.length; i < max; i++) {
+            if (! mySubs[i].matchBind(args, subs[i], bindings)) {
+            	return false;
+            }
+    	}
+    	return true;
     }
 
     /**
@@ -96,9 +117,14 @@
         if (priority > PR_EEXPR) {
             out.print("(");
         }
-        myFirst.subPrintOn(out, PR_EEXPR);
-        out.println();
-        mySecond.subPrintOn(out, PR_EEXPR);
+        boolean first = true;
+    	for (int i = 0, max = mySubs.length; i < max; i++) {
+            if (! first) {
+		        out.println();
+            }
+            first = false;
+	        mySubs[i].subPrintOn(out, PR_EEXPR);
+    	}
         if (priority > PR_EEXPR) {
             out.print(")");
         }
@@ -107,10 +133,12 @@
     /**
      *
      */
-    public EExpr first() { return myFirst; }
+    public EExpr[] subs() { return mySubs; }
 
     /**
-     *
+     * Append subs in place of the receiver.
      */
-    public EExpr second() { return mySecond; }
+    protected void appendTo(List accum) {
+     	appendAllTo(accum, mySubs);
+    }
 }



1.24      +4 -7      e/src/jsrc/org/erights/e/elang/evm/SlotExpr.java

Index: SlotExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/SlotExpr.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- SlotExpr.java	2001/09/07 05:49:20	1.23
+++ SlotExpr.java	2001/11/09 01:17:20	1.24
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
@@ -60,17 +60,14 @@
     /*package*/ StaticScope computeStaticScope() {
         FlexMap namesRead = FlexMap.fromTypes(String.class, Void.class);
         namesRead.put(myNoun.name(), null);
-        return new StaticScope(namesRead.snapshot(),
-                               StaticScope.EmptyMap,
-                               false,
-                               StaticScope.EmptyMap);
+        return StaticScope.scopeRead(namesRead.snapshot());
     }
 
     /**
      *
      */
-    /*package*/ Object subEval(Scope[] pov, boolean onlyFlag) {
-        return pov[0].getSlot(myNoun.name());
+    /*package*/ Object subEval(EvalContext ctx, boolean forValue) {
+        return myNoun.getSlot(ctx);
     }
 
     /**



1.16      +24 -3     e/src/jsrc/org/erights/e/elang/evm/StaticScope.java

Index: StaticScope.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/StaticScope.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- StaticScope.java	2001/09/07 05:49:20	1.15
+++ StaticScope.java	2001/11/09 01:17:20	1.16
@@ -34,15 +34,16 @@
     static public final ConstMap
         EmptyMap = FlexMap.fromTypes(String.class, Void.class).snapshot();
 
-    static public final StaticScope
-        EmptyScope = new StaticScope(EmptyMap, EmptyMap, false, EmptyMap);
+    static public final StaticScope 
+        EmptyScope = new StaticScope(EmptyMap, EmptyMap, false, EmptyMap),
+        META_SCOPE = new StaticScope(EmptyMap, EmptyMap, true, EmptyMap);
 
     private ConstMap myNamesRead;
     private ConstMap myNamesSet;
     private boolean myScopeExprFlag;
     private ConstMap myNamesOut;
 
-    public StaticScope(ConstMap namesRead,
+    private StaticScope(ConstMap namesRead,
                        ConstMap namesSet,
                        boolean hasScopeExpr,
                        ConstMap namesOut) {
@@ -50,6 +51,26 @@
         myNamesSet = namesSet;
         myScopeExprFlag = hasScopeExpr;
         myNamesOut = namesOut;
+    }
+    
+    static public StaticScope
+    scopeAssign(ConstMap namesSet) {
+        return new StaticScope(EmptyMap, namesSet, false, EmptyMap);
+    }
+
+    static public StaticScope
+    scopeRead(ConstMap namesRead) {
+        return new StaticScope(namesRead, EmptyMap, false, EmptyMap);
+    }
+
+    static public StaticScope
+    scopeDefine(ConstMap namesOut) {
+        return new StaticScope(EmptyMap, EmptyMap, false, namesOut);
+    }
+
+    static public StaticScope
+    scopeMeta() {
+        return META_SCOPE;
     }
 
     /**



1.13      +5 -10     e/src/jsrc/org/erights/e/elang/evm/SuchThatPattern.java

Index: SuchThatPattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/SuchThatPattern.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- SuchThatPattern.java	2001/09/07 05:49:20	1.12
+++ SuchThatPattern.java	2001/11/09 01:17:20	1.13
@@ -19,7 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.Thrower;
@@ -95,22 +95,17 @@
     /**
      *
      */
-    /*package*/ Scope testMatch(Scope scope,
+    /*package*/ void testMatch(EvalContext ctx,
                                 Object specimen,
                                 OneArgFunc optEjector)
     {
-        scope = mySubPattern.testMatch(scope, specimen, optEjector);
-        if (scope == null) {
-            return null;
-        }
-        Scope[] pov = scope.newPov();
-        if (myTest.evalBool(pov)) {
-            return pov[0];
-        } else {
+        mySubPattern.testMatch(ctx, specimen, optEjector);
+        if (! myTest.evalBool(ctx)) {
             throw Thrower.toEject(optEjector,
                                   "such-that expression was false");
         }
     }
+
 
     /**
      *



1.10      +26 -90    e/src/jsrc/org/erights/e/elang/evm/VarPattern.java

Index: VarPattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/VarPattern.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- VarPattern.java	2001/09/07 05:49:20	1.9
+++ VarPattern.java	2001/11/09 01:17:20	1.10
@@ -19,17 +19,12 @@
 Contributor(s): ______________________________________.
 */
 
-import org.erights.e.elang.interp.ScopeSetup;
-import org.erights.e.elang.scope.Scope;
+import org.erights.e.elang.scope.EvalContext;
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.E;
-import org.erights.e.elib.ref.Ref;
 import org.erights.e.elib.slot.Slot;
 import org.erights.e.elib.slot.SlotGuard;
-import org.erights.e.elib.tables.ConstMap;
-import org.erights.e.elib.tables.FlexList;
-import org.erights.e.elib.tables.FlexMap;
 import org.erights.e.elib.util.OneArgFunc;
 
 import java.io.IOException;
@@ -59,124 +54,65 @@
  * @see org.erights.e.elang.evm.FinalPattern
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public class VarPattern extends Pattern {
+public class VarPattern extends NounPattern {
 
+    private NounExpr myNoun;
+    private EExpr mySlotGuard;
+   
     /**
-     * A set of all the variable names that may not be shadowed (ie,
-     * redefined)
-     */
-    static public final ConstMap NonShadowable
-        = ScopeSetup.universal().asMap();
-
-    private String myVarName;
-    private EExpr mySlotGuardExpr;
-
-    /**
      * If 'varName' would shadow a non-shadowable, throw a (XXX to be
      * defined) exception instead.  <p>
      *
      * If the VarPattern would not be well-formed, throw a (XXX to be
      * defined) exception instead.  <p>
      */
-    public VarPattern(String varName, EExpr slotGuardExpr) {
-        myVarName = varName;
-        mySlotGuardExpr = slotGuardExpr;
-        if (NonShadowable.maps(myVarName)) {
-            throw new RuntimeException("can't redefine " + myVarName);
-        }
-        ensureWellFormed();
-    }
+    public VarPattern(String varName, NounExpr noun, EExpr guardExpr) {
+        super(varName);
+        myNoun = noun;
+        mySlotGuard = guardExpr;
+        ensureWellFormed(mySlotGuard);
+    }
+    public VarPattern(String varName, EExpr guardExpr) {
+        this(varName, new NounExpr(varName), guardExpr);
+    }    
 
     /**
      *
      */
-    private void ensureWellFormed() {
-        StaticScope smScope = mySlotGuardExpr.staticScope();
-        if (smScope.namesUsed().maps(myVarName)) {
-            throw new RuntimeException
-                ("kernel VarPattern cycle not allowed: " + myVarName);
-        }
-        if (smScope.namesOut().maps(myVarName)) {
-            throw new RuntimeException
-                ("kernel VarPattern shadow not allowed: " + myVarName);
-        }
-    }
-
-    /**
-     *
-     */
     public Object welcome(ETreeVisitor visitor) {
-        return visitor.visitVarPattern(myVarName, mySlotGuardExpr);
-    }
-
-    /**
-     *
-     */
-    /*package*/ StaticScope computeStaticScope() {
-        FlexMap namesOut = FlexMap.fromTypes(String.class, Void.class);
-        namesOut.put(myVarName, null);
-        StaticScope result = new StaticScope(StaticScope.EmptyMap,
-                                             StaticScope.EmptyMap,
-                                             false,
-                                             namesOut.snapshot());
-        result = result.add(mySlotGuardExpr.staticScope());
-        return result;
+        return visitor.visitVarPattern(optName(), mySlotGuard);
     }
 
-    /**
-     *
-     */
-    public boolean matchBind(Object[] args,
-                             Object specimen,
-                             FlexList bindings)
-    {
-        VarPattern other;
-        try {
-            other = (VarPattern)Ref.resolution(specimen);
-        } catch (ClassCastException cce) {
-            //using a try/catch since success is typical and we have
-            //to pay for the test in the cast anyway
-            return false;
-        }
-        return (myVarName.equals(other.myVarName)
-                && matchBind(mySlotGuardExpr,
-                             args,
-                             other.mySlotGuardExpr,
-                             bindings));
+    public NounExpr getNoun() {
+        return myNoun;
     }
-    /**
-     * A VarPattern will never return null for this.  It is named
-     * 'optName' because it is polymorphic with IgnorePattern
-     */
-    public String optName()         { return myVarName; }
 
     /**
      *
      */
-    public EExpr slotGuardExpr() { return mySlotGuardExpr; }
+    protected EExpr guardExpr() { return mySlotGuard; }
 
     /**
      *
      */
     public void subPrintOn(TextWriter out, int priority) throws IOException {
-        out.print("var ", myVarName, " :");
-        mySlotGuardExpr.subPrintOn(out, PR_ORDER);
+        out.print("var ");
+        super.subPrintOn(out, priority);
     }
 
     /**
      *
      */
-    /*package*/ Scope testMatch(Scope scope,
+    /*package*/ void testMatch(EvalContext ctx,
                                 Object specimen,
                                 OneArgFunc optEjector)
     {
-        Scope[] pov = scope.newPov();
-        //Because of the well-formedness criterea, we may safely evaluate
+        //Because of the well-formedness criterea, we may safely evaluate 
         //this in the wrong order
-        Object sg = mySlotGuardExpr.subEval(pov, false);
-        SlotGuard slotGuard = (SlotGuard)E.as(sg, SlotGuard.class);
+        Object sg = mySlotGuard.subEval(ctx, true);
+        SlotGuard slotGuard = (SlotGuard) E.as(sg, SlotGuard.class);
         Slot slot = slotGuard.makeSlot(specimen, optEjector);
-        pov[0] = pov[0].bindSlot(myVarName, slot);
-        return pov[0];
+        myNoun.initSlot(ctx, slot);
     }
+
 }



1.18      +1 -0      e/src/jsrc/org/erights/e/elang/interp/Help.java

Index: Help.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/interp/Help.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- Help.java	2001/09/07 05:49:21	1.17
+++ Help.java	2001/11/09 01:17:21	1.18
@@ -31,6 +31,7 @@
 import java.io.StringWriter;
 
 
+
 /**
  * Implements the E help command
  *



1.12      +10 -9     e/src/jsrc/org/erights/e/elang/interp/InteractiveInterp.java

Index: InteractiveInterp.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/interp/InteractiveInterp.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- InteractiveInterp.java	2001/10/03 18:05:28	1.11
+++ InteractiveInterp.java	2001/11/09 01:17:21	1.12
@@ -83,7 +83,7 @@
 
     private ExternalRef myFarSelf;
     private EParser myParser;
-    private Scope[] myTopPov;
+    private Scope myTopScope;
 
     private boolean myExpandFlag = false;
     private boolean myVerboseFlag = false;
@@ -112,7 +112,7 @@
 
                               Runner runner,
                               EParser parser,
-                              Scope[] topPov,
+                              Scope topScope,
 
                               boolean expandFlag,
                               boolean verboseFlag)
@@ -124,7 +124,7 @@
 
         myFarSelf = new ExternalRef(runner, this);
         myParser = parser;
-        myTopPov = topPov;
+        myTopScope = topScope;
 
         myExpandFlag = expandFlag;
         myVerboseFlag = verboseFlag;
@@ -162,7 +162,7 @@
      *
      */
     public Scope getTopScope() {
-        return myTopPov[0];
+        return myTopScope;
     }
 
     /**
@@ -200,7 +200,7 @@
      *
      */
     public void setTopScope(Scope newScope) {
-        myTopPov[0] = newScope;
+        myTopScope = newScope;
     }
 
     /**
@@ -267,7 +267,6 @@
                                                 props,
                                                 interpPromise);
         }
-        Scope[] topPov = optTopScope.newPov();
 
         boolean expandFlag = Interp.testProp(props, "e.interp.expand");
         boolean verboseFlag = Interp.testProp(props, "e.interp.verbose");
@@ -280,7 +279,7 @@
 
                         runner,
                         parser,
-                        topPov,
+                        optTopScope,
 
                         expandFlag,
                         verboseFlag);
@@ -355,14 +354,16 @@
         try {
             if (myExpandFlag) {
                 myOuts.print("# expansion: ");
-                eExpr.lnPrintOn(myOuts.indent("#   "));
+                // HACK to see transformed source tree
+                EExpr.TheLastTransformed.lnPrintOn(myOuts.indent("#   "));
+                //eExpr.lnPrintOn(myOuts.indent("#   "));
                 myOuts.println();
                 myOuts.println();
             }
 
             Object result = null;
             try {
-                result = Ref.resolution(eExpr.eval(myTopPov));
+                result = Ref.resolution(eExpr.eval(myTopScope));
                 pushResult(result);
             } catch (Throwable t) {
                 result = Ref.broken(t);



1.75      +27 -12    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.74
retrieving revision 1.75
diff -u -r1.74 -r1.75
--- Interp.java	2001/10/27 17:27:42	1.74
+++ Interp.java	2001/11/09 01:17:21	1.75
@@ -94,7 +94,7 @@
 
     private ExternalRef myFarSelf;
     private EParser myParser;
-    private Scope[] myTopPov;
+    private Scope myTopScope;
 
     private boolean myVerboseFlag = false;
 
@@ -118,7 +118,7 @@
 
                               Runner runner,
                               EParser parser,
-                              Scope[] topPov,
+                              Scope topScope,
 
                               boolean verboseFlag)
     {
@@ -129,7 +129,7 @@
 
         myFarSelf = new ExternalRef(runner, this);
         myParser = parser;
-        myTopPov = topPov;
+        myTopScope = topScope;
 
         myVerboseFlag = verboseFlag;
     }
@@ -166,7 +166,7 @@
      *
      */
     public Scope getTopScope() {
-        return myTopPov[0];
+        return myTopScope;
     }
 
     /**
@@ -195,7 +195,7 @@
      *
      */
     public void setTopScope(Scope newScope) {
-        myTopPov[0] = newScope;
+        myTopScope = newScope;
     }
 
     /**
@@ -312,7 +312,6 @@
                                                 props,
                                                 interpPromise);
         }
-        Scope[] topPov = optTopScope.newPov();
 
         boolean verboseFlag = testProp(props, "e.interp.verbose");
 
@@ -324,7 +323,7 @@
 
                         runner,
                         parser,
-                        topPov,
+                        optTopScope,
 
                         verboseFlag);
         interpResolver.resolve(result);
@@ -424,8 +423,7 @@
         myShouldBlock = false;
         myShouldExit = false;
         myOptProblem = null;
-
-        eExpr.eval(myTopPov);
+        eExpr.eval(myTopScope);
     }
 
     /**
@@ -433,7 +431,7 @@
      */
     private void interpretOne() {
         try {
-            EExpr optExpr = (EExpr)myParser.optParse();
+            EExpr optExpr = (EExpr) myParser.optParse();
             if (null != optExpr) {
                 E.call(myFarSelf, "evalPrint", optExpr);
             }
@@ -479,6 +477,16 @@
 
     /**
      *
+>>>> ORIGINAL
+     * Return null if program succeeded.  Otherwise, return the problem with
+     * which it failed.  A NeedMoreException, though, throws straight
+     * through.
+==== THEIRS
+==== YOURS
+     * Return null if program succeeded.  Otherwise, return the problem with
+     * which it failed.  A NeedMoreException, though, throws straight
+     * through.
+<<<<
      */
     public Throwable interpret() {
         while (true) {
@@ -579,7 +587,6 @@
         Properties sysProps = System.getProperties();
         TextWriter outs = new TextWriter(PrintStreamWriter.out(), true);
         TextWriter errs = new TextWriter(PrintStreamWriter.err(), true);
-
         while (args.size() >= 1) {
             String option = (String)args.get(0);
             // "-" isn't considered an option
@@ -651,7 +658,6 @@
             //Even without an eprops.txt, if there's an argument, just
             //proceed normally.
         }
-
         //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.
@@ -692,10 +698,19 @@
         TraceController.start(sysProps);
         initSwingLnF(props);
 
+        long start = System.currentTimeMillis();
         if (null == interp.interpret()) {
+            printTime(start);
             System.exit(0);
         } else {
+            printTime(start);
             errorExit(errs, props);
         }
+    }
+
+    static private void
+    printTime(long start) {
+        long stop = System.currentTimeMillis();
+        System.out.println("Run after initialization: " + (stop - start) + " ms");
     }
 }



1.4       +4 -3      e/src/jsrc/org/erights/e/elang/interp/LazyEvalSlot.java

Index: LazyEvalSlot.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/interp/LazyEvalSlot.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- LazyEvalSlot.java	2001/09/07 05:49:21	1.3
+++ LazyEvalSlot.java	2001/11/09 01:17:21	1.4
@@ -76,9 +76,10 @@
      */
     public Object getValue() {
         if (null != myOptSource) {
-            EExpr eExpr = (EExpr)EParser.run(myOptSource);
-            Scope scope = (Scope)E.as(myOptScope, Scope.class);
-            myOptValue = eExpr.eval(scope.sprout().newPov());
+            //System.out.println("Lazy eval: " + myOptSource);
+            EExpr eExpr = (EExpr) EParser.run(myOptSource);
+            Scope scope = (Scope) E.as(myOptScope, Scope.class);
+            myOptValue = eExpr.eval(scope.sprout());
             myOptScope = null;
             myOptSource = null;
         }



1.35      +18 -62    e/src/jsrc/org/erights/e/elang/interp/LoaderScope.java

Index: LoaderScope.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/interp/LoaderScope.java,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- LoaderScope.java	2001/09/07 05:49:21	1.34
+++ LoaderScope.java	2001/11/09 01:17:21	1.35
@@ -21,21 +21,16 @@
 import org.erights.e.develop.exception.ThrowableSugar;
 import org.erights.e.elang.evm.EExpr;
 import org.erights.e.elang.scope.Scope;
-import org.erights.e.elang.scope.ScopeImpl;
 import org.erights.e.elang.syntax.EParser;
-import org.erights.e.elib.eio.EPrintable;
 import org.erights.e.elib.eio.TextWriter;
-import org.erights.e.elib.eio.UnQuote;
 import org.erights.e.elib.prim.StaticMaker;
 import org.erights.e.elib.ref.Ref;
 import org.erights.e.elib.ref.Resolver;
 import org.erights.e.elib.slot.FinalSlot;
 import org.erights.e.elib.slot.FinalSlotMaker;
 import org.erights.e.elib.slot.Slot;
-import org.erights.e.elib.tables.ConstMap;
 import org.erights.e.elib.tables.FlexMap;
 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.meta.java.net.URLSugar;
 
@@ -47,10 +42,8 @@
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-/*package*/ class LoaderScope extends Scope implements EPrintable {
+/*package*/ class LoaderScope extends Loader {
 
-    static private final Scope[] NO_SCOPES = {};
-
     private Scope myUnivScope;
     private ClassLoader myOptLoader;
 
@@ -59,7 +52,7 @@
      * (for safe classes), PackageScopes (for packages), or whatever value a
      * .emaker file evaluated to, when interpreted in the universalScope.
      */
-    private FlexMap myLocals;
+    private FlexMap myAlreadyImported;
 
     /**
      *
@@ -67,7 +60,7 @@
     private LoaderScope(Scope univScope, ClassLoader optLoader) {
         myUnivScope = univScope;
         myOptLoader = optLoader;
-        myLocals = FlexMap.fromTypes(String.class, FinalSlot.class);
+        myAlreadyImported = FlexMap.fromTypes(String.class, FinalSlot.class);
     }
 
     /**
@@ -124,6 +117,9 @@
      * If not found, throws an exception.  Sets isConfinedPtr[0] according to
      * whether the result is itself confined (transitively immutable &
      * non-authority granting, or safe to treat as such).
+     *
+     * TODO each load starts with a clean universal scope in which additional
+     * outers are not visible outside the loaded module.
      */
     private Object getValue(String fqName, boolean[] isConfinedPtr) {
         if ("*".equals(fqName)) {
@@ -142,21 +138,25 @@
         //XXX todo: look for E prefix as package
         Twine eSource = optESource(fqName);
         if (null != eSource) {
-            EExpr eExpr = (EExpr)EParser.run(eSource);
-            Scope univ = myUnivScope.sprout();
+            EExpr eExpr = (EExpr) EParser.run(eSource);
             //XXX Once we have the :confined auditor, we should detect
             //whether this object passes this auditor.
             isConfinedPtr[0] = false;
-            return eExpr.eval(univ.newPov());
+            return eExpr.eval(myUnivScope.sprout());
         }
         throw new RuntimeException(fqName + " not found");
     }
 
+    public Object get(String name) {
+        return getLocalSlot(name).getValue();
+    }
+
     /**
      * Must handle cyclic imports
      */
     public Slot getLocalSlot(String fqName) {
-        Slot result = (Slot)myLocals.get(fqName, null);
+//System.out.println("LoaderScope.getting: " + fqName);
+        Slot result = (Slot) myAlreadyImported.get(fqName, null);
         if (null != result) {
             //XXX Once we detect that an emaker is confined and cache it for
             // longer, we need to also somehow check if a later ESource is
@@ -170,11 +170,11 @@
             return result;
         }
         Object[] promise = Ref.promise();
-        Ref ref = (Ref)promise[0];
-        Resolver resolver = (Resolver)promise[1];
+        Ref ref = (Ref) promise[0];
+        Resolver resolver = (Resolver) promise[1];
 
         result = FinalSlotMaker.THE_ONE.makeSlot(ref, null);
-        myLocals.put(fqName, result, true);
+        myAlreadyImported.put(fqName, result, true);
         Object value;
         //start with it set to false, so we'll also remove fqName if getValue
         //throws
@@ -185,7 +185,7 @@
             if (!keep[0]) {
                 //keep[0] says that the stored association is itself
                 //confined.  If not, remove it.
-                myLocals.removeKey(fqName, true);
+                myAlreadyImported.removeKey(fqName, true);
             }
         }
         resolver.resolve(value);
@@ -195,52 +195,8 @@
     /**
      *
      */
-    public Scope snapshot() {
-        return new ScopeImpl(NO_SCOPES, locals());
-    }
-
-    /**
-     *
-     */
-    public UnQuote bindings() {
-        return new UnQuote("<fully qualified names>\n" +
-                "    evaluate to the package or statics-wrapper");
-    }
-
-    /**
-     *
-     */
-    public Scope bindSlot(String name, Slot slot)
-         throws AlreadyDefinedException
-    {
-        throw new RuntimeException("Loader scopes cannot be extended");
-    }
-
-    /**
-     *
-     */
-    public ConstMap locals() {
-        return myLocals.snapshot();
-    }
-
-    /**
-     *
-     */
-    public Scope[] parents() {
-        return NO_SCOPES;
-    }
-
-    /**
-     *
-     */
     public void printOn(TextWriter out) throws IOException {
         out.print("<import:*>");
     }
 
-    /**
-     *
-     */
-    public void invalidate() {
-        myLocals = FlexMap.fromTypes(String.class, FinalSlot.class);
-    }
 }



1.21      +7 -52     e/src/jsrc/org/erights/e/elang/interp/PackageScope.java

Index: PackageScope.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/interp/PackageScope.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- PackageScope.java	2001/09/07 05:49:21	1.20
+++ PackageScope.java	2001/11/09 01:17:21	1.21
@@ -18,34 +18,27 @@
 
 Contributor(s): ______________________________________.
 */
-import org.erights.e.elang.scope.Scope;
-import org.erights.e.elang.scope.ScopeImpl;
-import org.erights.e.elib.eio.EPrintable;
 import org.erights.e.elib.eio.TextWriter;
-import org.erights.e.elib.eio.UnQuote;
-import org.erights.e.elib.slot.Slot;
-import org.erights.e.elib.tables.ConstMap;
-import org.erights.e.elib.util.AlreadyDefinedException;
 
 import java.io.IOException;
 
+import java.io.IOException;
+
 /**
  * Provides access to the java fully-qualified class namespace as a scope
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-/*package*/ class PackageScope extends Scope implements EPrintable {
+/*package*/ class PackageScope extends Loader {
 
-    static private final Scope[] NO_SCOPES = {};
-
-    private Scope mySubstrate;
+    private Loader mySubstrate;
     private String myProtocol;
     private String myPrefix;
 
     /**
      *
      */
-    /*package*/ PackageScope(Scope substrate,
+    /*package*/ PackageScope(Loader substrate,
                              String protocol,
                              String fqName)
     {
@@ -60,47 +53,9 @@
 
     /**
      *
-     */
-    public Scope snapshot() {
-        return new ScopeImpl(NO_SCOPES, locals());
-    }
-
-    /**
-     *
-     */
-    public UnQuote bindings() {
-        return new UnQuote(myPrefix + "<qualified names>\n" +
-                "    evaluate to the package or statics-wrapper");
-    }
-
-    /**
-     *
-     */
-    public Scope bindSlot(String name, Slot slot)
-         throws AlreadyDefinedException
-    {
-        throw new RuntimeException("Package scopes cannot be extended");
-    }
-
-    /**
-     *
-     */
-    public Slot getLocalSlot(String name) {
-        return mySubstrate.getLocalSlot(myPrefix + name);
-    }
-
-    /**
-     *
-     */
-    public ConstMap locals() {
-        throw new RuntimeException("XXX locals() not yet implemented");
-    }
-
-    /**
-     *
      */
-    public Scope[] parents() {
-        return NO_SCOPES;
+    public Object get(String name) {
+        return mySubstrate.get(myPrefix + name);
     }
 
     /**



1.67      +213 -181  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.66
retrieving revision 1.67
diff -u -r1.66 -r1.67
--- ScopeSetup.java	2001/10/27 17:27:42	1.66
+++ ScopeSetup.java	2001/11/09 01:17:21	1.67
@@ -20,9 +20,12 @@
 */
 
 import org.capml.quasi.XMLQuasiParser;
-import org.erights.e.elang.scope.MutableScope;
+import org.erights.e.elang.evm.LiteralNounExpr;
+import org.erights.e.elang.evm.LiteralSlotNounExpr;
+import org.erights.e.elang.evm.OuterNounExpr;
+import org.erights.e.elang.scope.OuterScope;
 import org.erights.e.elang.scope.Scope;
-import org.erights.e.elang.scope.ScopeImpl;
+import org.erights.e.elang.scope.ScopeMap;
 import org.erights.e.elang.syntax.EParser;
 import org.erights.e.elib.base.ClassDesc;
 import org.erights.e.elib.base.MessageDesc;
@@ -43,30 +46,30 @@
 import org.erights.e.elib.slot.SimpleSlotMaker;
 import org.erights.e.elib.slot.Slot;
 import org.erights.e.elib.slot.SlotDefiner;
-import org.erights.e.elib.slot.SlotGuard;
 import org.erights.e.elib.slot.VoidMaker;
 import org.erights.e.elib.tables.ConstMap;
-import org.erights.e.elib.tables.FlexMap;
+import org.erights.e.elib.tables.Equalizer;
 import org.erights.e.elib.tables.Twine;
 import org.erights.e.elib.util.ClassCache;
 import org.erights.e.meta.java.io.FileGetter;
 
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
 
 /**
  * The initial namespace as seen by the E language programmer.
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public class ScopeSetup {
+abstract public class ScopeSetup {
 
     static private final Scope[] NO_SCOPES = {};
-
+    static private final Object[] NO_VARS = {};
+    // number of spaces to leave for more outers.
+    static private final int OUTER_SPACE = 1000;
     /**
-     * prevent instatiation
-     */
-    private ScopeSetup() {}
-
-    /**
      * return null if not found
      */
     static private Class getClass(String fqName) {
@@ -78,144 +81,119 @@
     }
 
     /**
+     * Return the set of noun names defined in the universal scope that
+     * may not be shadowed. <p>
      *
-     */
-    static private Scope scopeFromPairs(Scope[] parents, Object[][] pairs) {
-        FlexMap map = FlexMap.fromTypes(String.class, Object.class);
-        SlotGuard fsg = FinalSlotMaker.THE_ONE;
-
-        for (int i = 0; i < pairs.length; i++) {
-            if (pairs[i].length == 2) {
-                Slot slot = fsg.makeSlot(pairs[i][1], null);
-                map.put(pairs[i][0], slot, true);
-            } else if (pairs[i].length == 3) {
-                Twine source = Twine.fromString((String)pairs[i][2]);
-                map.put(pairs[i][0],
-                        new LazyEvalSlot(pairs[i][1], source),
-                        true);
-            } else {
-                throw new Error("internal: bad pair format");
-            }
-        }
-        return new ScopeImpl(parents, map.snapshot());
-    }
-
-    /**
-     * like scopeFromPairs, but with a single parent
+     * NOTE: these could be cached, but they are actually only used to
+     *       set a variable in NounExpr, so the cache is currently unneeded.
      */
-    static private Scope inherit(Scope parent, Object[][] pairs) {
-        Scope[] parents = { parent };
-        return scopeFromPairs(parents, pairs);
+    static public Set nonShadowable() {
+        return universal().keys();
     }
 
     /**
      * Returns a fresh instantiation of the universal scope.  This scope
      * contains only transitively immutable objects, or objects like the
-     * importer (bound to "import:") with transparent-enough caches.  It
+     * importer (bound to "import:") with transparent-enough caches.  pIt
      * conveys no substantial authority, and so can be given out freely.
      */
-    static public Scope universal() {
+    static private ScopeMaker universal() {
         Object[] promise = Ref.promise();
-        Ref univ = (Ref)promise[0];
-        Resolver univResolver = (Resolver)promise[1];
+        Ref univ = (Ref) promise[0];
+        Resolver univResolver = (Resolver) promise[1];
 
         promise = Ref.promise();
-        Ref importer = (Ref)promise[0];
-        Resolver importerResolver = (Resolver)promise[1];
+        Ref importer = (Ref) promise[0];
+        Resolver importerResolver = (Resolver) promise[1];
 
-
-        Object[][] universalPairs = {
-            /*
-             * The E expansion generates references to these:
-             */
-            { "null",           null },
-            { "false",          Boolean.FALSE },
-            { "true",           Boolean.TRUE },
-            { "throw",          Thrower.THE_ONE },
-            { "loop",           Loop.THE_ONE },
-
-            { "E",              univ,
-              "<import:org.erights.e.elang.interp.E>" },
-            { "ListMaker",      univ,
-              "def ListMaker0 {\n" +
+        ScopeMaker um = new ScopeMaker();
+        // The E expansion generates references to these:
+        um.comp("null",           null);
+        um.comp("false",          Boolean.FALSE);
+        um.comp("true",           Boolean.TRUE);
+        um.comp("throw",          Thrower.THE_ONE);
+        um.comp("loop",           Loop.THE_ONE);
+
+        um.init("E",              univ,                   // not uconstant
+            "<import:org.erights.e.elang.interp.E>");
+        um.comp("ListMaker",      univ,
+              "{def ListMaker0 {\n" +
               "    match [==\"run\", args] { args }\n" +
-              "}" },
+              "}}");
 
-            { "MapMaker",       ConstMap.GetMaker() },
-            { "TwineMaker",     Twine.TwineMaker },
-            { "SourceSpanMaker", SourceSpan.SourceSpanMaker },
-            { "Ref",            Ref.RefMaker },
-
-            { "PromiseMaker",   Ref.RefMaker }, //XXX deprecated?
-
-            { "ProtocolDescMaker", ProtocolDesc.ProtocolDescMaker },
-            { "MessageDescMaker",  MessageDesc.MessageDescMaker },
-            { "ParamDescMaker",    ParamDesc.ParamDescMaker },
-
-            { "settable",       SettableSlotMaker.THE_ONE },
-            { "final",          FinalSlotMaker.THE_ONE },
-            { "defineSlot",     SlotDefiner.THE_ONE },
-            { "any",            SimpleSlotMaker.THE_ONE },
-            { "void",           VoidMaker.THE_ONE },
-
-            { "promiseAllFulfilled", univ,
-              "<import:org.erights.e.elang.interp.promiseAllFulfilled>" },
-
-            /*
-             * Like the above, these are not shadowable and in the universal
-             * scope, but are not implicitly used by the E expansion.
-             */
-
-            { "help",           new Help() },
-            { "require",        univ,
-              "<import:org.erights.e.elang.interp.require>" },
-
-            { "nullOk",         NullOkMaker.THE_ONE },
-            { "near",           univ,
-              "<import:org.erights.e.elib.slot.near>" },
-
-            { "PassByCopy",     new RuinedSlot(new RuntimeException(
-                              "XXX PassByCopy auditor not yet implemented")) },
-            { "confined",       new RuinedSlot(new RuntimeException(
-                              "XXX confined auditor not yet implemented")) },
-
-            { "OrderedSpaceMaker", univ,
-              "<import:org.erights.e.elang.coord.OrderedSpaceMaker>" },
-
-            { "integer",        univ,
-              "OrderedSpaceMaker new(<import:java.math.BigInteger> asType(),"
-              +                    "\"integer\")" },
-            { "float64",        univ,
-              "OrderedSpaceMaker new(<import:java.lang.Double> TYPE(),"
-              +                    "\"float64\")" },
-            { "char",           univ,
-              "OrderedSpaceMaker new(<import:java.lang.Character> TYPE(),"
-              +                    "\"char\")" },
-
-            { "boolean",        ClassDesc.make(Boolean.class) },
-            { "String",         ClassDesc.make(String.class) },
-            { "Twine",          ClassDesc.make(Twine.class) },
-            { "pbc",            PassByConstructionGuard.THE_ONE },
-            { "TextWriter",     ClassDesc.make(TextWriter.class) },
-
-            { "import__uriGetter",   importer },
-            { "resource__uriGetter",
-                                StaticMaker.make(ResourceUriGetter.class) },
-            { "simple__quasiParser", SimpleQuasiParser.THE_ONE },
-            { "rx__quasiParser",     univ,
-              "<import:org.erights.e.elang.interp.PerlMatchMakerMaker>" },
-            { "e__quasiParser",      EParser.EParserMaker },
-            { "epatt__quasiParser",  univ,
-              "<import:org.erights.e.elang.syntax.epatt__quasiParser>" },
-            { "sml__quasiParser",    XMLQuasiParser.XMLQuasiParserMaker },
-
-            { "universalScope",      univ },
-        };
-        Scope result = scopeFromPairs(NO_SCOPES, universalPairs);
-
-        univResolver.resolve(result);
-        importerResolver.resolve(new LoaderScope(result));
-        return result;
+        um.comp("MapMaker",       ConstMap.GetMaker());
+        um.comp("TwineMaker",     Twine.TwineMaker);
+        um.comp("SourceSpanMaker", SourceSpan.SourceSpanMaker);
+        um.init("Ref",            Ref.RefMaker);          // not uconstant??
+        um.init("equalizer",       Equalizer.make());
+
+        um.init("PromiseMaker",   Ref.RefMaker); //XXX deprecated?
+
+        um.comp("ProtocolDescMaker", ProtocolDesc.ProtocolDescMaker);
+        um.comp("MessageDescMaker",  MessageDesc.MessageDescMaker);
+        um.comp("ParamDescMaker",    ParamDesc.ParamDescMaker);
+        um.comp("settable",       SettableSlotMaker.THE_ONE);
+        um.comp("final",          FinalSlotMaker.THE_ONE);
+        um.comp("defineSlot",     SlotDefiner.THE_ONE);
+        um.comp("any",            SimpleSlotMaker.THE_ONE);
+        um.comp("void",           VoidMaker.THE_ONE);
+        um.init("promiseAllFulfilled", univ,              // not uconstant?
+                "<import:org.erights.e.elang.interp.promiseAllFulfilled>");
+
+        /*
+         * Like the above, these are not shadowable and in the universal
+         * scope, but are not implicitly used by the E expansion.
+         */
+
+        um.init("help",           new Help());            // not uconstant
+        um.comp("require",        univ,
+                "<import:org.erights.e.elang.interp.require>");
+
+        um.comp("nullOk",         NullOkMaker.THE_ONE);
+        um.comp("near",           univ,
+                "<import:org.erights.e.elib.slot.near>");
+        um.comp("PassByCopy",     new RuinedSlot(new RuntimeException(
+                                "XXX PassByCopy auditor not yet implemented")));
+        um.comp("confined",       new RuinedSlot(new RuntimeException(
+                                "XXX confined auditor not yet implemented")));
+
+        um.comp("OrderedSpaceMaker",    univ,
+                "<import:org.erights.e.elang.coord.OrderedSpaceMaker>");
+        um.comp("integer",              univ,
+                "OrderedSpaceMaker new(<import:java.math.BigInteger> asType(),"
+                +                    "\"integer\")");
+        um.comp("float64",              univ,
+                "OrderedSpaceMaker new(<import:java.lang.Double> TYPE(),"
+                +                    "\"float64\")");
+        um.comp("char",                 univ,
+                "<import:org.erights.e.elang.coord.OrderedSpaceMaker>");
+        um.comp("OrderedSpaceMaker",    univ,
+                "OrderedSpaceMaker new(<import:java.lang.Character> TYPE(),"
+                +                    "\"char\")");
+
+        um.comp("boolean",        ClassDesc.make(Boolean.class));
+        um.comp("String",         ClassDesc.make(String.class));
+        um.comp("Twine",          ClassDesc.make(Twine.class));
+        um.comp("TextWriter",     ClassDesc.make(TextWriter.class));
+        um.comp("pbc",            PassByConstructionGuard.THE_ONE);
+
+        um.init("import__uriGetter",   importer);         // not uconstant!!
+        um.init("resource__uriGetter",                    // not uconstant!!
+                StaticMaker.make(ResourceUriGetter.class));
+        um.comp("simple__quasiParser", SimpleQuasiParser.THE_ONE);
+        um.comp("rx__quasiParser",     univ,
+            "<import:org.erights.e.elang.interp.PerlMatchMakerMaker>");
+        um.comp("e__quasiParser",      EParser.EParserMaker);
+        um.comp("epatt__quasiParser",  univ,
+            "<import:org.erights.e.elang.syntax.epatt__quasiParser>");
+        um.comp("sml__quasiParser",    XMLQuasiParser.XMLQuasiParserMaker);
+
+        um.init("universalScope",      univ);             // not uconstant
+        Scope realUniv = um.scope();
+
+        univResolver.resolve(realUniv);
+        importerResolver.resolve(new LoaderScope(realUniv));
+        return um;
     }
 
     /**
@@ -248,8 +226,6 @@
                                    ConstMap props,
                                    Object interpPromise)
     {
-        Scope univ = universal();
-
         // XXX need some decent way to handle magic powers.
         StaticMaker entropyMaker =
             StaticMaker.make(getClass("net.vattp.security.ESecureRandom"));
@@ -269,7 +245,6 @@
         } else {
             //We're distributed.  Obtain the powers.
             StaticMaker introducerMaker = StaticMaker.make(optIntroducerClass);
-
             Object[] pair = (Object[])E.call(introducerMaker,
                                              "newPair",
                                              props,
@@ -280,64 +255,121 @@
         }
 
         Object[] promise = Ref.promise();
-        Ref privScope = (Ref)promise[0];
-        Resolver privResolver = (Resolver)promise[1];
+        Ref privScope = (Ref) promise[0];
+        Resolver privResolver = (Resolver) promise[1];
 
-        Object[][] privPairs = {
-            { "file__uriGetter",    StaticMaker.make(FileGetter.class) },
-            { "fileURL__uriGetter", new URLGetter("file") },
-            { "http__uriGetter",    new URLGetter("http") },
-            { "ftp__uriGetter",     new URLGetter("ftp") },
-            { "gopher__uriGetter",  new URLGetter("gopher") },
-            { "news__uriGetter",    new URLGetter("news") },
-            { "cap__uriGetter",     optIntroducer },
-
-            { "unsafe__uriGetter",  new UnsafeLoaderScope() },
-            { "awt__uriGetter",     privScope,
-              "<unsafe:java.awt.*>" },
-            { "swing__uriGetter",   privScope,
-              "<unsafe:javax.swing.*>" },
-            { "JPanel__quasiParser", privScope,
-              "<import:org.erights.ex.swing.JPanelQParserMaker> " +
-              "new(awt__uriGetter, swing__uriGetter)" },
+        ScopeMaker pm = universal().copy();
+        pm.init("file__uriGetter",    StaticMaker.make(FileGetter.class));
+        pm.init("fileURL__uriGetter", new URLGetter("file"));
+        pm.init("http__uriGetter",    new URLGetter("http"));
+        pm.init("ftp__uriGetter",     new URLGetter("ftp"));
+        pm.init("gopher__uriGetter",  new URLGetter("gopher"));
+        pm.init("news__uriGetter",    new URLGetter("news"));
+        pm.init("cap__uriGetter",     optIntroducer);
+
+        pm.init("unsafe__uriGetter",  new UnsafeLoaderScope());
+        pm.init("awt__uriGetter",     privScope,
+            "<unsafe:java.awt.*>");
+        pm.init("swing__uriGetter",   privScope,
+            "<unsafe:javax.swing.*>");
+        pm.init("JPanel__quasiParser", privScope,
+            "<import:org.erights.ex.swing.JPanelQParserMaker> " +
+            "new(awt__uriGetter, swing__uriGetter)");
 
-            { "CommandMaker",       privScope,
+        pm.init("CommandMaker",       privScope,
               "<import:org.erights.e.elib.extern.CommandMakerAuthor>(" +
-                  "<unsafe:java.lang.Runtime> getRuntime())" },
+                  "<unsafe:java.lang.Runtime> getRuntime())");
 
-            { "stdout",             stdout },
-            { "stderr",             stderr },
-            { "print",              privScope,
-              "def print {\n" +
+        pm.init("stdout",             stdout);
+        pm.init("stderr",             stderr);
+        pm.init("print",              privScope,
+              "{def print {\n" +
               "    match [==\"run\", args] {\n" +
               "        stdout printAll(args)\n" +
               "    }\n" +
-              "}" },
-            { "println",            privScope,
-              "def println {\n" +
+              "}}");
+        pm.init("println",            privScope,
+              "{def println {\n" +
               "    match [==\"run\", args] {\n" +
               "        stdout printAll(args)\n" +
               "        stdout println()\n" +
               "    }\n" +
-              "}" },
-            { "interp",             interpPromise },
+              "}}");
+        pm.init("interp",             interpPromise);
 
-            { "entropy",            optEntropy },
-            { "timer",              optTimer },
-            { "tempTimer",          optTempTimer },
-            { "introducer",         optIntroducer },
-            { "sturdyRef",          optSturdifier },
-
-            { "privilegedScope",    privScope },
-        };
-        Scope priv = inherit(univ, privPairs);
+        pm.init("entropy",            optEntropy);
+        pm.init("timer",              optTimer);
+        pm.init("tempTimer",          optTempTimer);
+        pm.init("introducer",         optIntroducer);
+        pm.init("sturdyRef",          optSturdifier);
+
+        //pm.init("privilegedScope",    privScope);
+        Scope priv = pm.scope(interactive);
         privResolver.resolve(priv);
+        return priv;
+    }
 
-        if (interactive) {
-            Scope[] muParents = { priv };
-            return new MutableScope(muParents);
-        } else {
-            return priv.sprout();
+    static private class ScopeMaker {
+        static private final int DEFAULT_SIZE = 50;
+
+        private ArrayList myOuters;
+        private HashMap myBindings;
+
+        public ScopeMaker() {
+            this(new ArrayList(DEFAULT_SIZE),
+                 new HashMap(DEFAULT_SIZE));
+        }
+
+        private ScopeMaker(ArrayList outers, HashMap bindings) {
+            myOuters = outers;
+            myBindings = bindings;
+        }
+
+        public ScopeMaker copy() {
+            return new ScopeMaker(new ArrayList(myOuters),
+                                  new HashMap(myBindings));
+        }
+
+        public Set keys() { return myBindings.keySet(); }
+
+        public Scope scope() {
+            return scope(false);
+        }
+
+        public Scope scope(boolean isMutable) {
+            ScopeMap outerNouns = ScopeMap.make(myBindings);
+            int outerCount = myOuters.size();
+            int outerSpace = outerCount + OUTER_SPACE;
+            Slot[] outers = (Slot[]) myOuters.toArray(new Slot[outerSpace]);
+            return OuterScope.make(outerNouns, outers, outerCount, isMutable);
+        }
+
+        // generate a bindings for a noun that will be compiled into transformed code
+        public void comp(String name, Object value) {
+            myBindings.put(name, new LiteralNounExpr(name, value));
+        }
+
+        public void comp(String name, Object scope, String srcstr) {
+            Twine source = Twine.fromString(srcstr);
+            Slot slot = new LazyEvalSlot(scope, source);
+            myBindings.put(name, new LiteralSlotNounExpr(name, slot));
+        }
+
+        public void init(String name, Object value) {
+            Slot slot = FinalSlotMaker.THE_ONE.makeSlot(value, null);
+            initSlot(name, slot);
+        }
+
+        public void init(String name, Object scope, String srcstr) {
+            Twine source = Twine.fromString(srcstr);
+            Slot slot = new LazyEvalSlot(scope, source);
+            initSlot(name, slot);
+        }
+
+        private void initSlot(String name, Slot slot) {
+            int i = myOuters.size();
+            myOuters.add(slot);
+            myBindings.put(name, new OuterNounExpr(name, i));
         }
     }
 }



1.8       +10 -58    e/src/jsrc/org/erights/e/elang/interp/UnsafeLoaderScope.java

Index: UnsafeLoaderScope.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/interp/UnsafeLoaderScope.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- UnsafeLoaderScope.java	2001/09/07 05:49:21	1.7
+++ UnsafeLoaderScope.java	2001/11/09 01:17:21	1.8
@@ -18,20 +18,14 @@
 
 Contributor(s): ______________________________________.
 */
-import org.erights.e.elang.scope.Scope;
-import org.erights.e.elang.scope.ScopeImpl;
-import org.erights.e.elib.eio.EPrintable;
 import org.erights.e.elib.eio.TextWriter;
-import org.erights.e.elib.eio.UnQuote;
 import org.erights.e.elib.prim.StaticMaker;
 import org.erights.e.elib.ref.Ref;
 import org.erights.e.elib.ref.Resolver;
 import org.erights.e.elib.slot.FinalSlot;
 import org.erights.e.elib.slot.FinalSlotMaker;
 import org.erights.e.elib.slot.Slot;
-import org.erights.e.elib.tables.ConstMap;
 import org.erights.e.elib.tables.FlexMap;
-import org.erights.e.elib.util.AlreadyDefinedException;
 import org.erights.e.elib.util.ClassCache;
 
 import java.io.IOException;
@@ -41,10 +35,8 @@
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-/*package*/ class UnsafeLoaderScope extends Scope implements EPrintable {
+/*package*/ class UnsafeLoaderScope extends Loader {
 
-    static private final Scope[] NO_SCOPES = {};
-
     private ClassLoader myOptLoader;
 
     /**
@@ -81,7 +73,12 @@
     }
 
     /** exception if not found */
-    private Object getValue(String fqName) {
+    public Object get(String fqName) {
+        return getLocalSlot(fqName).getValue();
+    }
+
+    /** exception if not found */
+    private Object getWrapped(String fqName) {
         if ("*".equals(fqName)) {
             return this;
         } else if (fqName.endsWith(".*")) {
@@ -98,8 +95,8 @@
     /**
      * Must handle cyclic imports
      */
-    public Slot getLocalSlot(String fqName) {
-        Slot result = (Slot)myLocals.get(fqName, null);
+    private Slot getLocalSlot(String fqName) {
+        Slot result = (Slot) myLocals.get(fqName, null);
         if (null != result) {
             //XXX Should also somehow check if a later ESource is
             // available, and, if so, use it and (perhaps?) upgrade
@@ -115,7 +112,7 @@
         Object value;
         boolean done = false;
         try {
-            value = getValue(fqName);
+            value = getWrapped(fqName);
             done = true;
         } finally {
             if (!done) {
@@ -129,52 +126,7 @@
     /**
      *
      */
-    public Scope snapshot() {
-        return new ScopeImpl(NO_SCOPES, locals());
-    }
-
-    /**
-     *
-     */
-    public UnQuote bindings() {
-        return new UnQuote("<fully qualified names>\n" +
-                "    evaluate to the package or statics-wrapper");
-    }
-
-    /**
-     *
-     */
-    public Scope bindSlot(String name, Slot slot)
-         throws AlreadyDefinedException
-    {
-        throw new RuntimeException("Loader scopes cannot be extended");
-    }
-
-    /**
-     *
-     */
-    public ConstMap locals() {
-        return myLocals.snapshot();
-    }
-
-    /**
-     *
-     */
-    public Scope[] parents() {
-        return NO_SCOPES;
-    }
-
-    /**
-     *
-     */
     public void printOn(TextWriter out) throws IOException {
         out.print("<unsafe:*>");
-    }
-
-    /**
-     *
-     */
-    public void invalidate() {
-        myLocals = FlexMap.fromTypes(String.class, FinalSlot.class);
     }
 }



1.45      +64 -146   e/src/jsrc/org/erights/e/elang/scope/Scope.java

Index: Scope.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/scope/Scope.java,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- Scope.java	2001/10/01 08:31:04	1.44
+++ Scope.java	2001/11/09 01:17:22	1.45
@@ -19,16 +19,14 @@
 Contributor(s): ______________________________________.
 */
 import org.erights.e.develop.format.StringHelper;
+import org.erights.e.elang.evm.ENode;
+import org.erights.e.elang.evm.NounExpr;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.eio.UnQuote;
-import org.erights.e.elib.ref.Ref;
 import org.erights.e.elib.slot.FinalSlotMaker;
-import org.erights.e.elib.slot.RuinedSlot;
 import org.erights.e.elib.slot.Slot;
 import org.erights.e.elib.tables.ConstList;
 import org.erights.e.elib.tables.ConstMap;
-import org.erights.e.elib.tables.FlexList;
-import org.erights.e.elib.tables.FlexMap;
 import org.erights.e.elib.util.AlreadyDefinedException;
 
 import java.io.IOException;
@@ -44,16 +42,51 @@
  */
 public abstract class Scope {
 
+    protected ScopeMap myScopeMap;
+
+    static public Scope in(ENode node, EvalContext ctx) {
+        return new InnerScope(node.optScopeMap(), ctx);
+    }
+
+    protected Scope(ScopeMap map) {
+        myScopeMap = map;
+    }
+
+    abstract public EvalContext newContext(int numLocals);
+
+    abstract public Slot getSlot(String name);
+
     /**
-     *
+     * Gets the value of the slot associated with name.  Just a
+     * convenience implemented out of getSlot()
      */
-    public abstract Scope snapshot();
+    public Object get(String name) {
+        return getSlot(name).getValue();
+    }
+
+    /**
+      * The default put() is defined in the obvious fashion in
+      * terms of getSlot().setValue(newValue).  <p>
+     */
+     public void put(String name, Object newValue) {
+	 getSlot(name).setValue(newValue);
+     }
+
+    /**
+     * Return a new scope that does not share outers data structures with the receiver.
+     */
+    abstract public Scope sprout();
+
+    public ScopeMap scopeMap() { return myScopeMap; }
+
+    abstract public NounExpr reserveOuter(String name);
 
     /**
      *
      */
     public ConstMap asMap() {
-        Scope[] folks = parents();
+        throw new RuntimeException("TODO unimplemented");
+ /*       Scope[] folks = parents();
         if (0 == folks.length) {
             return locals();
         } else {
@@ -75,180 +108,65 @@
                 ruinTable.put(name, new RuinedSlot(problem));
             }
             return locals().or(ruinTable.snapshot().or(result));
+    */
         }
-    }
+
 
     /**
      * The default implementation here just works in terms of
-     * bindSlot(). <p>
+     * bindOuter(). <p>
      *
      * An interactive top-level Scope (a MutableScope) adds a
      * 'name' => 'slot' binding to itself if necessary.
      */
-    public Scope bindFinal(String name, Object theValue)
+    public void bindFinal(String name, Object theValue)
     throws AlreadyDefinedException {
-        return bindSlot(name,
-                        FinalSlotMaker.THE_ONE.makeSlot(theValue, null));
+	Slot slot = FinalSlotMaker.THE_ONE.makeSlot(theValue, null);
+        bindOuter(name, slot);
     }
 
     /**
      * Returns a string showing the bindings in this scope in a
-     * pleasant human readable format
+     * pleasant, human readable format
      */
     public UnQuote bindings() throws IOException {
         StringWriter buf = new StringWriter();
         final TextWriter os1 = new TextWriter(buf);
         final TextWriter os2 = os1.indent();
-        ConstMap map = asMap();
-        ConstList keys = ConstList.fromArray(map.getKeys()).sort();
-        int len = keys.size();
-        for (int i = 0; i < len; i++) {
+        Object names = myScopeMap.namesSet().toArray(new String[]{});
+        ConstList keys = ConstList.fromArray(names).sort();
+        for (int i = 0, len = keys.size(); i < len; i++) {
             String key = (String)keys.get(i);
             os1.print(key);
-            os2.lnPrint(((Slot)map.get(key)).getValue());
+            os2.lnPrint(get(key));
             os1.println();
         }
         return new UnQuote(StringHelper.canonical(buf.toString()));
     }
 
+    public String toString() {
+        try {
+            return bindings().toString();
+        } catch (IOException e) {
+            return "Could not print bindings";
+        }
+    }
+
     /**
      * A normal Scope returns a Scope just like this one, except for a
      * new local binding 'name' to 'slot'.  <p>
      *
-     * If this scope already has a local for 'name', bindSlot() normally
+     * If this scope already has a local for 'name', bindOuter() normally
      * throws AlreadyDefinedException.  But an interactive top-level Scope (a
      * MutableScope) adds a 'name' => 'slot' binding to itself if necessary.
-     * If there already is a local named 'name', bindSlot() replaces it.
-     */
-    public abstract Scope bindSlot(String name, Slot slot)
-    throws AlreadyDefinedException;
-
-    /**
-     * Return a scope derived from this scope in which each name (key) in
-     * names is bound to a reference broken by problem
-     */
-    public Scope brokenBindings(ConstMap names, Throwable problem) {
-        Scope result = this;
-        String[] keys = (String[])names.getKeys(String.class);
-        for (int i = 0; i < keys.length; i++) {
-            String name = keys[i];
-            result = result.bindFinal(name, Ref.broken(problem));
-        }
-        return result;
-    }
-
-    /**
-     * This Scope potentially inherits from other Scopes.  Of all
-     * these Scope, which ones defines 'name'?  A child has priority over
-     * its parents, but multiple answers reflect an ambiguity.
+     * If there already is a local named 'name', bindOuter() replaces it.
      */
-    private void definingScopes(String name, FlexList result) {
-        if (getLocalSlot(name) != null) {
-            result.push(this);
-        } else {
-            Scope[] folks = parents();
-            for (int i = 0; i < folks.length; i++) {
-                folks[i].definingScopes(name, result);
-            }
-        }
-    }
+    public abstract void bindOuter(String name, Slot slot)
+	    throws AlreadyDefinedException;
 
     /**
-     * Gets the value of the slot associated with name.  Just a
-     * convenience implemented out of getSlot()
-     */
-    public Object get(String name) {
-        Slot slot = getSlot(name);
-        if (null == slot) {
-            throw new UndefinedVariableException(name + " not defined");
-
-        } else {
-            //If slot is a RuinedSlot, its getValue() throws the
-            //required exception.
-            //If slot is a SlotRef, its getValue() returns a synchronously
-            //resolving promise for the value of the promised slot
-            return slot.getValue();
-        }
-    }
-
-    /**
-     * If there is no association for 'name', getLocalSlot() returns null. <p>
-     *
-     * XXX This should be protected, but Java's peculiar "protected" rules
-     * prevent that.  It shouldn't be dangerous to make this public, but it
-     * bears examination.
-     *
-     * @returns nullOk;
-     */
-    public Slot getLocalSlot(String name) {
-        return (Slot)locals().get(name, null);
-    }
-
-    /**
-     * What slot is associated with 'name'?  Uses the first
-     * association up the inheritance chain.  If there are multiple
-     * definingScopes(), getSlot() returns a RuinedSlot.
-     *
-     * If there is no association for 'name', getSlot() returns null.
      *
-     * @returns nullOk;
-     */
-    public Slot getSlot(String name) {
-        Slot result = getLocalSlot(name);
-        if (result != null) {
-            return result;
-        }
-        FlexList definers = FlexList.make();
-        definingScopes(name, definers);
-        int num = definers.size();
-        if (num == 1) {
-            return ((Scope)definers.get(0)).getSlot(name);
-        } else if (num == 0) {
-            return null;
-        } else {
-            return new RuinedSlot(new AlreadyDefinedException
-                                  ("inheritance conflict for " + name));
-        }
-    }
-
-    /**
-     *
-     */
-    public abstract ConstMap locals();
-
-    /**
-     * Convenience method: returns a singleton array whose one element
-     * is this scope.
-     */
-    public Scope[] newPov() {
-        Scope[] result = { this };
-        return result;
-    }
-
-    /**
-     * The Scopes this one immediately inherits from.
-     */
-    public abstract Scope[] parents();
-
-    /**
-     * The default put() is defined in the obvious fashion in
-     * terms of getSlot().setValue(newValue).  <p>
-     */
-    public void put(String name, Object newValue) {
-        Slot slot = getSlot(name);
-        if (slot == null) {
-            throw new UndefinedVariableException(name + " not defined");
-        } else {
-            slot.setValue(newValue);
-        }
-    }
-
-    /**
-     * Makes and returns a new Scope that inherits from this one.
-     * This new Scope has an empty set of locals.
      */
-    public Scope sprout() {
-        Scope[] newParents = { this };
-        return new ScopeImpl(newParents);
+    protected ConstMap locals() { return null;  // TODO
     }
 }



1.83      +12 -13    e/src/jsrc/org/erights/e/elang/syntax/EBuilder.java

Index: EBuilder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/EBuilder.java,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -r1.82 -r1.83
--- EBuilder.java	2001/11/06 06:27:32	1.82
+++ EBuilder.java	2001/11/09 01:17:22	1.83
@@ -26,6 +26,7 @@
 import org.erights.e.elang.evm.DefineExpr;
 import org.erights.e.elang.evm.EExpr;
 import org.erights.e.elang.evm.EMethod;
+import org.erights.e.elang.evm.EMethodNode;
 import org.erights.e.elang.evm.EScript;
 import org.erights.e.elang.evm.EscapeExpr;
 import org.erights.e.elang.evm.FinalPattern;
@@ -93,6 +94,7 @@
     static /*package*/ final EExpr DEFINESLOT   = noun("defineSlot");
     static /*package*/ final EExpr ANY          = noun("any");
     static /*package*/ final EExpr VOID         = noun("void");
+    static /*package*/ final EExpr EQUALIZER    = noun("equalizer");
 
     static /*package*/ final EExpr
     PROMISE_ALL_FULFILLED                       = noun("promiseAllFulfilled");
@@ -994,13 +996,14 @@
     /**
      *
      */
-    /*package*/ EMethod method(Object msgPatt, Object bodyExpr) {
-        MsgPatt patt = (MsgPatt)msgPatt;
-        return new EMethod("", //XXX will be a docComment
+    /*package*/ EMethodNode method(Object msgPatt, Object bodyExpr) {
+        MsgPatt patt = (MsgPatt) msgPatt;
+        EMethod meth = new EMethod("", //XXX will be a docComment
                            patt.verb(),
                            patt.patterns(),
                            patt.returnGuard(),
                            (EExpr)bodyExpr);
+        return new EMethodNode(patt.verb(), patt.patterns().length, meth);
     }
 
     /**
@@ -1059,8 +1062,8 @@
      *
      */
     /*package*/ EScript eScript(Object optMethods, Object optMatcher) {
-        return new EScript((EMethod[])typedArray(optMethods,
-                                                 EMethod.class),
+        return new EScript((EMethodNode[]) typedArray(optMethods, 
+                                                 EMethodNode.class),
                            (Matcher)optMatcher);
     }
 
@@ -1284,7 +1287,7 @@
      *
      */
     /*package*/ EExpr same(Object x, Object y) {
-        return call(REF, "same", list(x, y));
+        return call(EQUALIZER, "isSame", list(x, y));
     }
 
     /**
@@ -1303,11 +1306,7 @@
      * XXX Currently, parts.length must be >= 1
      */
     /*package*/ EExpr sequence(EExpr[] parts) {
-        EExpr result = parts[0];
-        for (int j = 1; j < parts.length; j++) {
-            result = sequence(result, parts[j]);
-        }
-        return result;
+        return new SeqExpr(parts);
     }
 
     /**
@@ -1318,14 +1317,14 @@
             throw new RuntimeException
                 ("internal: legacy of old return-value syntax");
         }
-        return new SeqExpr((EExpr)x, (EExpr)y);
+        return sequence(new EExpr[] { (EExpr)x, (EExpr)y });
     }
 
     /**
      *
      */
     /*package*/ EExpr sequence(Object x, Object y, Object z) {
-        return sequence(sequence(x, y), z);
+        return sequence(new EExpr[] { (EExpr)x, (EExpr)y, (EExpr)z });
     }
 
     /**



1.12      +8 -8      e/src/jsrc/org/erights/e/elang/visitors/AlphaRenameVisitor.java

Index: AlphaRenameVisitor.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/visitors/AlphaRenameVisitor.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- AlphaRenameVisitor.java	2001/09/06 09:55:47	1.11
+++ AlphaRenameVisitor.java	2001/11/09 01:17:22	1.12
@@ -67,7 +67,7 @@
     /**
      *
      */
-    private FlexMap nest() {
+    private FlexMap innerRenames() {
         if (myOptRenamings == null) {
             myOptRenamings = FlexMap.fromTypes(String.class, String.class);
             return null;
@@ -140,7 +140,7 @@
      *
      */
     public Object visitEscapeExpr(Pattern hatch, EExpr body) {
-        FlexMap optOriginal = nest();
+        FlexMap optOriginal = innerRenames();
         try {
             return super.visitEscapeExpr(hatch, body);
         } finally {
@@ -153,7 +153,7 @@
      *
      */
     public Object visitHideExpr(EExpr body) {
-        FlexMap optOriginal = nest();
+        FlexMap optOriginal = innerRenames();
         try {
             return super.visitHideExpr(body);
         } finally {
@@ -166,7 +166,7 @@
      *
      */
     public Object visitIfExpr(EExpr test, EExpr then, EExpr els) {
-        FlexMap optOriginal = nest();
+        FlexMap optOriginal = innerRenames();
         FlexMap elsMap = fork();
         try {
             test = xformEExpr(test);
@@ -184,7 +184,7 @@
      *
      */
     public Object visitCatchExpr(EExpr attempt, Pattern patt, EExpr catcher) {
-        FlexMap optOriginal = nest();
+        FlexMap optOriginal = innerRenames();
         FlexMap catchMap = fork();
         try {
             attempt = xformEExpr(attempt);
@@ -203,7 +203,7 @@
      *
      */
     public Object visitFinallyExpr(EExpr attempt, EExpr unwinder) {
-        FlexMap optOriginal = nest();
+        FlexMap optOriginal = innerRenames();
         FlexMap finallyMap = fork();
         try {
             attempt = xformEExpr(attempt);
@@ -231,7 +231,7 @@
                                EExpr returnGuard,
                                EExpr body)
     {
-        FlexMap optOriginal = nest();
+        FlexMap optOriginal = innerRenames();
         try {
             return super.visitEMethod(docComment,
                                       verb,
@@ -250,7 +250,7 @@
     public Object visitMatcher(Pattern patt,
                                EExpr body)
     {
-        FlexMap optOriginal = nest();
+        FlexMap optOriginal = innerRenames();
         try {
             return super.visitMatcher(patt, body);
         } finally {



1.20      +61 -35    e/src/jsrc/org/erights/e/elang/visitors/CopyVisitor.java

Index: CopyVisitor.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/visitors/CopyVisitor.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- CopyVisitor.java	2001/09/06 09:55:47	1.19
+++ CopyVisitor.java	2001/11/09 01:17:22	1.20
@@ -5,7 +5,7 @@
 Distributed E Language Implementation 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.erights.org/download/mmlicense.html
+http://www.erights.org/mmlicense.html
 
 Software distributed under the License is distributed on an "AS IS"
 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
@@ -28,6 +28,7 @@
 import org.erights.e.elang.evm.DefineExpr;
 import org.erights.e.elang.evm.EExpr;
 import org.erights.e.elang.evm.EMethod;
+import org.erights.e.elang.evm.EMethodNode;
 import org.erights.e.elang.evm.ENode;
 import org.erights.e.elang.evm.EScript;
 import org.erights.e.elang.evm.EscapeExpr;
@@ -80,32 +81,42 @@
     }
 
     /**
+     * Return a version of the receiver for a nested scope.  The default
+     * is that there is no difference.
+     *
+     * NOTE: this needs to generate a new visitor by tlking ot the decorator.
+     */
+    protected CopyVisitor
+    nest() {
+        return this;
+    }
+
+    /**
      * For use from E.  Java/ELib users should use the more strongly typed
      * xform* methods.
      */
     public Object run(Object optENode) {
         if (optENode == null) {
             return null;
-
         } else if (optENode instanceof ENode) {
-            ENode eNode = (ENode)optENode;
-            ENode result = (ENode)eNode.welcome(myDecorator);
-            result.defineSource(eNode.optSource());
-            return result;
-
+            return xformNode((ENode) optENode);
         } else {
-            ENode[] eNodes = (ENode[])optENode;
+            ENode[] eNodes = (ENode[]) optENode;
             Class elementClass = eNodes.getClass().getComponentType();
-            ENode[] result = (ENode[])Array.newInstance(elementClass,
-                                                        eNodes.length);
+            ENode[] result = (ENode[]) Array.newInstance(elementClass,
+                                                         eNodes.length);
             for (int i = 0; i < eNodes.length; i++) {
-                result[i] = (ENode)run(eNodes[i]);
+                result[i] = (ENode) run(eNodes[i]);
             }
             return result;
         }
     }
-
 
+    public ENode xformNode(ENode eNode) {
+        ENode result = (ENode) eNode.welcome(myDecorator);
+        result.defineSource(eNode.optSource());
+        return result;
+    }
 
     /**************************** EExprs **************************/
 
@@ -116,7 +127,6 @@
         return (EExpr)run(optEExpr);
     }
 
-
     /**
      *
      */
@@ -157,8 +167,9 @@
      *
      */
     public Object visitEscapeExpr(Pattern hatch, EExpr body) {
-        return new EscapeExpr(xformPattern(hatch),
-                              xformEExpr(body));
+        CopyVisitor t = nest();
+        return new EscapeExpr(t.xformPattern(hatch),
+                              t.xformEExpr(body));
     }
 
 
@@ -166,7 +177,7 @@
      *
      */
     public Object visitHideExpr(EExpr body) {
-        return new HideExpr(xformEExpr(body));
+        return new HideExpr(nest().xformEExpr(body));
     }
 
 
@@ -174,9 +185,10 @@
      *
      */
     public Object visitIfExpr(EExpr test, EExpr then, EExpr els) {
-        return new IfExpr(xformEExpr(test),
-                          xformEExpr(then),
-                          xformEExpr(els));
+        CopyVisitor t = nest();
+        return new IfExpr(t.xformEExpr(test),
+                          t.xformEExpr(then),
+                          nest().xformEExpr(els));
     }
 
 
@@ -257,9 +269,12 @@
     /**
      *
      */
-    public Object visitSeqExpr(EExpr first, EExpr second) {
-        return new SeqExpr(xformEExpr(first),
-                           xformEExpr(second));
+    public Object visitSeqExpr(EExpr[] subs) {
+    	EExpr[] newSubs = new EExpr[subs.length];
+    	for (int i = 0, max = subs.length; i< max; i++) {
+    		newSubs[i] = xformEExpr(subs[i]);
+    	}
+    	return new SeqExpr(newSubs);
     }
 
 
@@ -283,9 +298,10 @@
      *
      */
     public Object visitCatchExpr(EExpr attempt, Pattern patt, EExpr catcher) {
-        return new CatchExpr(xformEExpr(attempt),
-                             xformPattern(patt),
-                             xformEExpr(catcher));
+        CopyVisitor catchScope = nest();
+        return new CatchExpr(nest().xformEExpr(attempt),
+                             catchScope.xformPattern(patt),
+                             catchScope.xformEExpr(catcher));
     }
 
 
@@ -293,8 +309,8 @@
      *
      */
     public Object visitFinallyExpr(EExpr attempt, EExpr unwinder) {
-        return new FinallyExpr(xformEExpr(attempt),
-                               xformEExpr(unwinder));
+        return new FinallyExpr(nest().xformEExpr(attempt),
+                               nest().xformEExpr(unwinder));
     }
 
 
@@ -419,11 +435,19 @@
     /**
      *
      */
-    public Object visitEScript(EMethod[] optMethods,
+    public Object visitEScript(EMethodNode[] optMethods,
                                Matcher optMatcher)
     {
-        return new EScript((EMethod[])run(optMethods),
-                           xformMatcher(optMatcher));
+        if (null == optMethods) {
+            return new EScript(null, xformMatcher(optMatcher));
+        }
+        int mcount = optMethods.length;
+        EMethodNode[] mnodes = new EMethodNode[mcount];
+        for (int i = 0; i < mcount; i++) {
+            EMethod meth = xformMethod(optMethods[i].method());
+            mnodes[i] = new EMethodNode(meth);
+        }
+        return new EScript(mnodes, xformMatcher(optMatcher));
     }
 
 
@@ -436,11 +460,12 @@
                                EExpr returnGuard,
                                EExpr body)
     {
+        CopyVisitor t = nest();
         return new EMethod(docComment,
                            verb,
-                           xformPatterns(patterns),
-                           xformEExpr(returnGuard),
-                           xformEExpr(body));
+                           t.xformPatterns(patterns),
+                           t.xformEExpr(returnGuard),
+                           t.xformEExpr(body));
     }
 
 
@@ -450,7 +475,8 @@
     public Object visitMatcher(Pattern patt,
                                EExpr body)
     {
-        return new Matcher(xformPattern(patt),
-                           xformEExpr(body));
+        CopyVisitor t = nest();
+        return new Matcher(t.xformPattern(patt),
+                           t.xformEExpr(body));
     }
 }



1.17      +5 -6      e/src/jsrc/org/erights/e/elang/visitors/ETreeVisitor.java

Index: ETreeVisitor.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/visitors/ETreeVisitor.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- ETreeVisitor.java	2001/09/06 09:55:47	1.16
+++ ETreeVisitor.java	2001/11/09 01:17:22	1.17
@@ -5,7 +5,7 @@
 Distributed E Language Implementation 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.erights.org/download/mmlicense.html
+http://www.erights.org/mmlicense.html
 
 Software distributed under the License is distributed on an "AS IS"
 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
@@ -22,7 +22,7 @@
 */
 
 import org.erights.e.elang.evm.EExpr;
-import org.erights.e.elang.evm.EMethod;
+import org.erights.e.elang.evm.EMethodNode;
 import org.erights.e.elang.evm.EScript;
 import org.erights.e.elang.evm.ListPattern;
 import org.erights.e.elang.evm.Matcher;
@@ -38,8 +38,7 @@
 
     /**************************** EExprs **************************/
 
-
-    /**
+     /**
      * varName ":=" rValue. <p>
      *
      * Does a setValue on the slot named by varName to the value of rValue
@@ -210,7 +209,7 @@
      * @see <a href="{@docroot}/../elang/kernel/SeqExpr.html">The
      * Kernel-E Sequence Expression</a>
      */
-    Object visitSeqExpr(EExpr first, EExpr second);
+    Object visitSeqExpr(EExpr[] subs);
 
     /**
      * "&" varName. <p>
@@ -360,7 +359,7 @@
      * @see <a href="{@docroot}/../elang/kernel/EScript.html">The
      * Kernel-E Script Node</a>
      */
-    Object visitEScript(EMethod[] optMethods, Matcher optMatcher);
+    Object visitEScript(EMethodNode[] optMethods, Matcher optMatcher);
 
     /**
      * "##" docComment <br>



1.17      +1 -1      e/src/jsrc/org/erights/e/elib/base/Callable.java

Index: Callable.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/Callable.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- Callable.java	2001/09/06 09:55:47	1.16
+++ Callable.java	2001/11/09 01:17:22	1.17
@@ -35,7 +35,7 @@
 
     /**
      * Returns a description of the type the object alleges to implement.
-     * Should probably be moved to the optMeta.
+     * Should probably be moved to the getOptMeta.
      */
     TypeDesc getAllegedType();
 



1.7       +19 -1     e/src/jsrc/org/erights/e/elib/base/Ejection.java

Index: Ejection.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/Ejection.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Ejection.java	2001/09/06 09:55:47	1.6
+++ Ejection.java	2001/11/09 01:17:22	1.7
@@ -26,6 +26,24 @@
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
 public class Ejection extends Throwable {
-    public Ejection() { super(); }
+    public Ejection() {}
     public Ejection(String s) { super(s); }
+
+    /**
+     * Make sure to not print the stack trace that was not collected.
+     */
+    public void printStackTrace(java.io.PrintStream s) {
+        s.println("Ejection: " + getMessage());
+    }
+    public void printStackTrace(java.io.PrintWriter s) {
+        s.println("Ejection: " + getMessage());
+    }
+
+    /**
+     * Suppress stack trace construction.
+     */
+    public Throwable fillInStackTrace() {
+        // DO NOTHING
+        return this;
+    }
 }



1.16      +22 -1     e/src/jsrc/org/erights/e/elib/base/MethodNode.java

Index: MethodNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/MethodNode.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- MethodNode.java	2001/09/06 09:55:47	1.15
+++ MethodNode.java	2001/11/09 01:17:22	1.16
@@ -19,6 +19,7 @@
 Contributor(s): ______________________________________.
 */
 
+import org.erights.e.elib.quasi.MatchMaker;
 import org.erights.e.elib.slot.SimpleSlotMaker;
 import org.erights.e.elib.slot.ValueGuard;
 import org.erights.e.elib.tables.ConstList;
@@ -31,7 +32,7 @@
  * @see org.erights.e.elib.prim.VTable
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public abstract class MethodNode extends ParseNode implements Script {
+public abstract class MethodNode implements Script, MatchMaker {
 
     /**
      *
@@ -95,5 +96,25 @@
             return otv != null && aVerb.equals(otv);
         }
         return false;
+    }
+
+// For MatchMaker
+    /**
+     *
+     */
+    public abstract boolean matchBind(Object[] args,
+                                      Object specimen,
+                                      FlexList bindings);
+
+    /**
+     *
+     */
+    public ConstList matchBind(Object[] args, Object specimen) {
+        FlexList bindings = FlexList.make();
+        if (matchBind(args, specimen, bindings)) {
+            return bindings.snapshot();
+        } else {
+            return null;
+        }
     }
 }



1.27      +11 -2     e/src/jsrc/org/erights/e/elib/base/ParseNode.java

Index: ParseNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/ParseNode.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- ParseNode.java	2001/09/07 05:49:22	1.26
+++ ParseNode.java	2001/11/09 01:17:22	1.27
@@ -27,6 +27,9 @@
 
 import java.io.IOException;
 
+import java.io.IOException;
+import java.io.StringWriter;
+
 /**
  * A ParseNode of a program written in "kernel E".  A program written
  * in E is immediately expanded to kernel E, hopefully passing
@@ -70,12 +73,18 @@
      * all subclasses.
      */
     public void defineSource(SourceSpan source)
-         throws AlreadyDefinedException {
-
+    throws AlreadyDefinedException {
         if (myOptSource != null) {
             throw new AlreadyDefinedException("source");
         }
         myOptSource = source;
+    }
+
+    /**
+     * Clear the
+     */
+    protected void cleanCopy() {
+        myOptSource = null;
     }
 
     /**



1.28      +1 -2      e/src/jsrc/org/erights/e/elib/prim/JavaMemberNode.java

Index: JavaMemberNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/JavaMemberNode.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- JavaMemberNode.java	2001/09/07 05:49:22	1.27
+++ JavaMemberNode.java	2001/11/09 01:17:22	1.28
@@ -134,13 +134,13 @@
     public Object execute(Object self, String aVerb, Object[] args) {
         try {
             Object result;
+            // TODO the typical case probably requires coercion (esp. ints)
 
             //make the typical case faster: first try invoking without
             //coercion.  If we get into trouble, then try coercing the
             //arguments.
             try {
                 result = innerExecute(self, args);
-
             } catch (IllegalArgumentException ex) {
                 Object newSelf = E.as(self, receiverType());
                 Object[] newArgs = coerceArgs(args, null);
@@ -154,7 +154,6 @@
             }
             myOkCoverageFlag = true;
             return result;
-
         } catch (Throwable t) {
             myBadCoverageFlag = true;
             throw ExceptionMgr.asSafe(t);



1.28      +13 -0     e/src/jsrc/org/erights/e/elib/tables/EMap.java

Index: EMap.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/EMap.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- EMap.java	2001/10/02 23:38:32	1.27
+++ EMap.java	2001/11/09 01:17:22	1.28
@@ -139,6 +139,19 @@
     }
 
     /**
+     * Do these tables have any keys in common?
+     */
+    public boolean intersects(EMap other) {
+        Object[] keys = (Object[]) getKeys(Object.class);
+        for (int i = 0, max = keys.length; i < max; i++) {
+            if (other.contains(keys[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * How many entries are in the table?
      */
     public abstract int size();



1.27      +122 -66   e/src/jsrc/org/erights/e/elib/tables/Equalizer.java

Index: Equalizer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/Equalizer.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- Equalizer.java	2001/10/02 23:38:32	1.26
+++ Equalizer.java	2001/11/09 01:17:22	1.27
@@ -2,6 +2,7 @@
 
 import org.erights.e.develop.exception.ThrowableSugar;
 import org.erights.e.elib.prim.E;
+import org.erights.e.elib.prim.Queue;
 import org.erights.e.elib.ref.Ref;
 import org.erights.e.elib.util.ClassCache;
 
@@ -84,39 +85,44 @@
         }
     }
 
-    private final Object myLeft;
-    private final Object myRight;
+    static private final int INITIAL_SIZE = 30;
 
+    static private Queue TheCachedEqualizers = new Queue(Equalizer.class);
+
+    private Object[] myLefts;
+    private Object[] myRights;
+    private int myMaxSofar;
+
     /**
      *
      */
-    private Equalizer(Object left, Object right) {
-        myLeft = left;
-        myRight = right;
+    static public Equalizer make() {
+        Equalizer res = (Equalizer) TheCachedEqualizers.optDequeue();
+        return null == res ? new Equalizer() : res;
     }
 
     /**
-     * Two Equalizers are the same if their two objects are EQ (Java's "=="),
-     * independent of order.
+     *
      */
-    public boolean equals(Object other) {
-        Equalizer oth;
-        try {
-            oth = (Equalizer)other;
-        } catch (ClassCastException cce) {
-            return false;
-        }
-        return (myLeft == oth.myLeft && myRight == oth.myRight)
-            || (myLeft == oth.myRight && myRight == oth.myLeft);
+    private Equalizer() {
+        myLefts = new Object[INITIAL_SIZE];
+        myRights = new Object[INITIAL_SIZE];
     }
 
     /**
-     * The hashCode() must depend only on the EQ identities of myLeft and
-     * myRight independent of their order.
+     * The implementation of Ref.same(left, right)
+     *
+     * @see org.erights.e.elib.ref.Ref#same
      */
-    public int hashCode() {
-        return System.identityHashCode(myLeft)
-             ^ System.identityHashCode(myRight);
+    static public boolean same(Object left, Object right)
+    throws NotSettledException {
+        if (left == right) {
+            return true;
+        }
+        Equalizer eq = make();
+        boolean res = eq.isSame(left, right);
+        TheCachedEqualizers.enqueue(eq);
+        return res;
     }
 
     /**
@@ -124,10 +130,19 @@
      *
      * @see org.erights.e.elib.ref.Ref#same
      */
-    static public boolean same(Object left, Object right)
+    public boolean isSame(Object left, Object right)
     throws NotSettledException {
-        FlexMap sofar = FlexMap.fromTypes(Equalizer.class, Void.TYPE);
-        return same(left, right, sofar);
+        boolean res = same(left, right, 0);
+        clear();
+        return res;
+    }
+
+    private void clear() {
+        for (int i = 0; i < myMaxSofar; i++) {
+            myLefts[i] = null;
+            myRights[i] = null;
+        }
+        myMaxSofar = 0;
     }
 
     /**
@@ -149,9 +164,8 @@
     /**
      *
      */
-    static private boolean same(Object left, Object right, FlexMap sofar)
+    private boolean same(Object left, Object right, int sofar)
     throws NotSettledException {
-
         if (left == right) {
             if (Ref.isResolved(left) && Ref.isResolved(right)) {
                 //sameness of resolved objects is reflexive
@@ -168,51 +182,51 @@
             return false;
         }
 
+        // TODO should the original or the simplified version be
+        // stored in the cache
+        // rest of sameness happens after simplification.
+        left = simplify(left);
+        right = simplify(right);
+
         // It's the hypothesis we're already investigating.
         // Must happen before simplification, since it depends on EQ.
-        Equalizer hypothesis = new Equalizer(left, right);
-        if (sofar.maps(hypothesis)) {
+        boolean res = findSofar(left, right, sofar);
+        if (res) {
             return true;
         }
 
-        // rest of sameness happens after simplification.
-        left = simplify(left);
-        right = simplify(right);
-
         // sameness is recursive thru arrays
-        if (left.getClass().isArray() && right.getClass().isArray()) {
+        final boolean leftArray = left.getClass().isArray();
+        final boolean rightArray = right.getClass().isArray();
+        if (leftArray && rightArray) {
             int len = Array.getLength(left);
             if (Array.getLength(right) != len) {
                 return false;
             }
-            sofar.put(hypothesis, null, true);
-            try {
-                for (int i = 0; i < len; i++) {
-                    if (!same(Array.get(left,i), Array.get(right,i), sofar)) {
-                        return false;
-                    }
+            int sofarther = pushSofar(left, right, sofar);
+            for (int i = 0; i < len; i++) {
+                final Object newLeft = Array.get(left,i);
+                final Object newRight = Array.get(right,i);
+                if (! same(newLeft, newRight, sofarther)) {
+                    return false;
                 }
-                return true;
-            } finally {
-                sofar.removeKey(hypothesis, true);
             }
-        } else if (left.getClass().isArray() || right.getClass().isArray()) {
+            return true;
+        } else if (leftArray || rightArray) {
             return false;
         }
 
         // sameness is recursive thru transparent Selfless objects
-        if (left instanceof Selfless && right instanceof Selfless) {
-            sofar.put(hypothesis, null, true);
-            try {
-                Selfless a = (Selfless)left;
-                Selfless b = (Selfless)right;
-                return same(a.getCanonicalState(),
-                            b.getCanonicalState(),
-                            sofar);
-            } finally {
-                sofar.removeKey(hypothesis, true);
-            }
-        } else if (left instanceof Selfless || right instanceof Selfless) {
+        final boolean leftSelfless = left instanceof Selfless;
+        final boolean rightSelfless = right instanceof Selfless;
+        if (leftSelfless && rightSelfless) {
+            int sofarther = pushSofar(left, right, sofar);
+            Selfless a = (Selfless)left;
+            Selfless b = (Selfless)right;
+            return same(a.getCanonicalState(),
+                        b.getCanonicalState(),
+                        sofarther);
+        } else if (leftSelfless || rightSelfless) {
             return false;
         }
 
@@ -223,16 +237,15 @@
         Class leftClass = left.getClass();
         Class rightClass = right.getClass();
         if (Selfless.HONORARY.has(leftClass)
-            && Selfless.HONORARY.has(rightClass))
+                && Selfless.HONORARY.has(rightClass))
         {
             return left.equals(right);
-
-        /* unnecessary:
-         * } else if (Selfless.HONORARY.has(leftClass)
-         *            || Selfless.HONORARY.has(rightClass))
-         * {
-         *     return false;
-         */
+            /* unnecessary:
+             * } else if (Selfless.HONORARY.has(leftClass)
+             *            || Selfless.HONORARY.has(rightClass))
+             * {
+             *     return false;
+             */
         }
 
         // sameness is synchronous but monotonic
@@ -286,26 +299,69 @@
             }
             return true;
         }
-
         // isSettled is recursive thru transparent Selfless objects
         if (obj instanceof Selfless) {
             sofar.put(original, null);
             Selfless a = (Selfless)obj;
             return isSettled(a.getCanonicalState(), sofar);
         }
-
         // unresolved things are not settled
         if (!Ref.isResolved(obj)) {
             return false;
         }
-
         // everything else is settled
         return true;
     }
 
+    private boolean findSofar(Object left, Object right, int sofar) {
+        int lhash = System.identityHashCode(left);
+        int rhash = System.identityHashCode(right);
+        if (rhash < lhash) {
+            Object t = left;
+            left = right;
+            right = t;
+        }
+        for (int i = 0, max = sofar; i < max; i++) {
+            if (left == myLefts[i] && right == myRights[i]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private int pushSofar(Object left, Object right, int sofar) {
+        if (sofar >= myMaxSofar) {
+            myMaxSofar = sofar + 1;
+            int len = myLefts.length;
+            if (sofar <= len) {
+                int newLen = (len * 2) + 32;
+                Object[] newLefts = new Object[newLen];
+                System.arraycopy(myLefts, 0, newLefts, 0, len);
+                myLefts = newLefts;
+                Object[] newRights = new Object[newLen];
+                System.arraycopy(myLefts, 0, newLefts, 0, len);
+                myRights = newRights;
+            }
+        }
+        int lhash = System.identityHashCode(left);
+        int rhash = System.identityHashCode(right);
+        if (rhash < lhash) {
+            Object t = left;
+            left = right;
+            right = t;
+        }
+        // add candidate to sofar
+        myLefts[sofar] = left;
+        myRights[sofar] = right;
+        int sofarther = sofar + 1;
+        return sofarther;
+    }
+
     /**
      * Two settled objects that are the same() must have the same
      * sameHash().  Only settled objects may be hashed.
+     *
+     * TODO this should be moved to SamenessKeyColumn
      */
     static /*package*/ int sameHash(Object obj) throws NotSettledException {
         return sameHash(obj, HASH_DEPTH);



1.2       +10 -10    e/src/test/esrc/pasteRun.updoc

Index: pasteRun.updoc
===================================================================
RCS file: /cvs/e/src/test/esrc/pasteRun.updoc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- pasteRun.updoc	1999/01/03 11:04:58	1.1
+++ pasteRun.updoc	2001/11/09 01:17:22	1.2
@@ -12,20 +12,20 @@
 >     }
 >     pastedString
 > }
-# value: <getPasteString>
-
+# value: <getPasteString>
+
 ? getPasteString()
-# value:     TheTokens[IMPORT]           = "import";
-#        
-
+# value:     TheTokens[IMPORT]           = "import";
+#        
+
 ? 
 
 ? println("abc")
-abc
-# value: abc
-
+abc
+# value: abc
 
 
+
 ? define interpret(sourceString) {
 >     define myEMainClass := import:org.erights.e.elang.syntax.EMain maker
 >     define myLineReader := import:org.erights.e.elang.syntax.LineReader maker new("println('b')")
@@ -34,8 +34,8 @@
 >     #why does it die in Emain?
 >     myEMain interpret(true)
 > }
-# value: <interpret>
-
+# value: <interpret>
+
 
 
 ? define CreatePasteRunWinMaker new(){



1.2       +10 -10    e/src/test/esrc/proxycommtest.updoc

Index: proxycommtest.updoc
===================================================================
RCS file: /cvs/e/src/test/esrc/proxycommtest.updoc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- proxycommtest.updoc	1999/01/03 11:04:58	1.1
+++ proxycommtest.updoc	2001/11/09 01:17:22	1.2
@@ -1,17 +1,17 @@
 ? define BootMaker := import:org.erights.e.boot.Boot maker
-# value: statics of org.erights.e.boot.Boot
-
+# value: statics of org.erights.e.boot.Boot
+
 ? BootMaker main(["test.proxy.ProxyCommTestApp"])
 ? 2 + 3
-# value: 5
-
+# value: 5
+
 ? define ipm := import:java.net.InetAddress maker
-# value: statics of java.net.InetAddress
-
+# value: statics of java.net.InetAddress
+
 ? ipm getByName("localhost")
-# value: localhost/127.0.0.1
-
+# value: localhost/127.0.0.1
+
 ? ipm getByName("127.0.0.1")
-# value: 127.0.0.1/127.0.0.1
-
+# value: 127.0.0.1/127.0.0.1
+
 ?  



1.2       +14 -14    e/src/test/esrc/title.updoc

Index: title.updoc
===================================================================
RCS file: /cvs/e/src/test/esrc/title.updoc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- title.updoc	1999/01/03 11:04:58	1.1
+++ title.updoc	2001/11/09 01:17:22	1.2
@@ -1,6 +1,6 @@
 ? define BrandMaker := import:org.erights.e.elang.sealing.Brand maker
-# value: statics of org.erights.e.elang.sealing.Brand
-
+# value: statics of org.erights.e.elang.sealing.Brand
+
 ? define makeTitleCompany new(name) {
 >     define [sealer, unsealer] := BrandMaker pair(name)
 >     define PurseMaker new(good) {
@@ -32,23 +32,23 @@
 >         to makePurse(good) { PurseMaker new(good) }
 >     }
 > }
-# value: <makeTitleCompany>
-
+# value: <makeTitleCompany>
+
 ? define jvm := makeTitleCompany new("Joe's Vars")
-# value: Joe's Vars title maint
-
+# value: Joe's Vars title maint
+
 ? define x := 3
-# value: 3
-
+# value: 3
+
 ? define xp := jvm makePurse(&x)
-# value: Joe's Vars purse: (3)
-
+# value: Joe's Vars purse: (3)
+
 ? x := 4
-# value: 4
-
+# value: 4
+
 ? xp
-# value: Joe's Vars purse: (4)
-
+# value: Joe's Vars purse: (4)
+
 ? define &y := xp
 # value: Joe's Vars purse: (4)