[e-cvs] cvs commit: e/src/jsrc/org/erights/e/ui/elmer EInterpAdapter.java

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Sun, 19 Aug 2001 02:35:56 -0400


markm       01/08/19 02:35:56

  Modified:    src/esrc/org/erights/e/elang/cmd cmdLoopMakerAuthor.emaker
                        cmdMakerMaker.emaker cmdMakerMaker.updoc
                        controlLoopMakerAuthor.emaker
                        controlLoopMakerAuthor.updoc
               src/jsrc/net/captp/jcomm ProxyOutputStream.java
               src/jsrc/org/erights/e/elang/interp ScopeSetup.java
               src/jsrc/org/erights/e/elib/base ParseNode.java
                        TextWriter.java
               src/jsrc/org/erights/e/elib/prim StaticMaker.java
               src/jsrc/org/erights/e/elib/ref Ref.java
               src/jsrc/org/erights/e/elib/serial PassByConstruction.java
                        Persistent.java Serializer.java Unserializer.java
               src/jsrc/org/erights/e/ui/elmer EInterpAdapter.java
  Log:
  change to command loop protocol

Revision  Changes    Path
1.3       +1 -1      e/src/esrc/org/erights/e/elang/cmd/cmdLoopMakerAuthor.emaker

Index: cmdLoopMakerAuthor.emaker
===================================================================
RCS file: /cvs/e/src/esrc/org/erights/e/elang/cmd/cmdLoopMakerAuthor.emaker,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- cmdLoopMakerAuthor.emaker	2001/08/17 05:48:57	1.2
+++ cmdLoopMakerAuthor.emaker	2001/08/19 06:35:55	1.3
@@ -27,7 +27,7 @@
             to getShowsJavaStack() :boolean { showsJavaStackFlag }
             to getShowsEStack()    :boolean { showsEStackFlag }
             to getInteractive()    :boolean { true }
-            to setExpand(newFlag)  { expandFlag := newFlag }
+            to setExpand(newFlag)         { expandFlag := newFlag }
             to setShowsJavaStack(newFlag) { showsJavaStackFlag := newFlag }
             to setShowsEStack(newFlag)    { showsEStackFlag := newFlag }
 



1.2       +37 -26    e/src/esrc/org/erights/e/elang/cmd/cmdMakerMaker.emaker

Index: cmdMakerMaker.emaker
===================================================================
RCS file: /cvs/e/src/esrc/org/erights/e/elang/cmd/cmdMakerMaker.emaker,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- cmdMakerMaker.emaker	2001/08/17 05:48:57	1.1
+++ cmdMakerMaker.emaker	2001/08/19 06:35:55	1.2
@@ -1,6 +1,5 @@
-def RuntimeException := <import:java.lang.RuntimeException> asType()
-def TwineException := 
-    <import:org.erights.e.elib.util.TwineException> asType()
+def TextWriterMaker := <import:org.erights.e.elib.base.TextWriter>
+def EParser := <import:org.erights.e.elang.syntax.EParser>
 
 # outputs prefix & returns indented TextWriter
 def commentBlock {
@@ -15,50 +14,62 @@
         out println()
     }
 }
+def takeBuf(out, keyword, buf) {
+    def str := buf toString()
+    if (str size() >= 1) {
+        commentBlock(out, keyword, str)
+        buf setLength(0)
+    }
+}
 
-class cmdMakerMaker(cmdLoop, out, err, trace) :any {
-    class cmdMaker(expr) :any {
+class cmdMakerMaker(cmdLoop, outBuf, errBuf) :any {
+    class cmdMaker(sourceCode) :any {
+        def [reportVow, reportRes] := PromiseMaker()
         def cmd() {
-            if (cmdLoop getExpand()) {
-                commentBlock(out, "expansionx", expr)
-            }
+            def [tw, sb] := TextWriterMaker makeBufferingPair()
             def pov := cmdLoop getTopPov()
             var success := true
             def result := try {
+                # should deal with embedded $-holes as result[i]
+                def expr := EParser(sourceCode)
+                if (cmdLoop getExpand()) {
+                    commentBlock(tw, "expansionx", expr)
+                }
                 expr eval(pov)
             } catch problem {
                 success := false
                 Ref broken(problem)
             }
             cmdLoop pushResult(result)
+            takeBuf(tw, "stdout", outBuf)
+            takeBuf(tw, "stderr", errBuf)
             if (success) {
                 if (result != null) {
-                    commentBlock(out, "valuex") quote(result)
-                    out println()
-                    out println()
+                    commentBlock(tw, "valuex") quote(result)
+                    tw println()
+                    tw println()
                 }
             } else {
                 def problem := Ref optProblem(result)
                 def leaf := problem leaf()
-                def leafType := leaf getAllegedType()
-                def printable := if (leafType == RuntimeException ||
-                                     leaf =~ ignore :TwineException) {
-                    leaf getMessage()
-                } else {
-                    leaf
+                tw indent("# ") print("# ", leaf)
+                def showJ := cmdLoop getShowsJavaStack()
+                def showE := cmdLoop getShowsEStack()
+                if (showJ || showE) {
+                    tw lnPrint("#")
                 }
-                
-                def indented := commentBlock(err, "problemx")
-                indented println(printable)
-                if (cmdLoop getShowsJavaStack()) {
-                    err indent("#   ") lnPrint(leaf javaStack())
+                if (showJ) {
+                    tw indent("#   ") lnPrint(leaf javaStack())
                 }
-                if (cmdLoop getShowsEStack()) {
-                    err indent("#   ") print(problem eStack())
+                if (showE) {
+                    tw indent("#   ") print(problem eStack())
                 }
-                err println()
-                err println()
+                tw println()
+                tw println()
             }
+            reportRes resolve(sb toString())
+            sb setLength(0)
         }
+        [reportVow, cmd]
     }
 }



1.3       +67 -27    e/src/esrc/org/erights/e/elang/cmd/cmdMakerMaker.updoc

Index: cmdMakerMaker.updoc
===================================================================
RCS file: /cvs/e/src/esrc/org/erights/e/elang/cmd/cmdMakerMaker.updoc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- cmdMakerMaker.updoc	2001/08/18 05:19:38	1.2
+++ cmdMakerMaker.updoc	2001/08/19 06:35:55	1.3
@@ -1,3 +1,6 @@
+    ? def TextWriterMaker := <import:org.erights.e.elib.base.TextWriter>
+    # value: <import:org.erights.e.elib.base.TextWriter>
+    
     ? def cmd__uriGetter := <import:org.erights.e.elang.cmd.*>
     # value: <import:org.erights.e.elang.cmd.*>
     
@@ -17,42 +20,79 @@
     
     ? def cmdLoopMaker := <cmd:cmdLoopMakerAuthor>(QueueMaker, SystemGC)
     # value: <cmdLoopMaker>
+    
+    ? def ScopeSetup := <unsafe:org.erights.e.elang.interp.ScopeSetup>
+    # value: <unsafe:org.erights.e.elang.interp.ScopeSetup>
     
-    ? def ScopeImplMaker := <unsafe:org.erights.e.elang.scope.ScopeImpl>
-    # value: <unsafe:org.erights.e.elang.scope.ScopeImpl>
+    ? def [altout, altoutBuf] := TextWriterMaker makeBufferingPair()
+    # value: [<TextWriter>, ]
     
-    ? def scope := ScopeImplMaker new([])
-    # value: org.erights.e.elang.scope.ScopeImpl@5dffbd
+    ? def [alterr, alterrBuf] := TextWriterMaker makeBufferingPair()
+    # value: [<TextWriter>, ]
     
-    ? scope asMap()
-    # value: [] asMap
+    ? def cmdLoop
+    # value: <Eventual ref>
+    
+    ? def props := interp getProps(); null
+    ? def privileged := ScopeSetup privileged(true,
+    >                                         altout,
+    >                                         alterr,
+    >                                         props,
+    >                                         cmdLoop)
+    # value: org.erights.e.elang.scope.MutableScope@3aa7d4
     
-    ? def cmdLoop := cmdLoopMaker new(["a", "b"],
-    >                                 interp getProps(),
-    >                                 scope)
+    ? def bind cmdLoop := cmdLoopMaker new(["a", "b"], props, privileged)
     # value: <cmdLoop>
     
-    ? def cmdMaker := cmdMakerMaker new(cmdLoop, stdout, stderr, stderr)
+    ? def cmdMaker := cmdMakerMaker new(cmdLoop, altoutBuf, alterrBuf)
     # value: <cmdMaker>
     
-    ? def cmd := cmdMaker new(e`2 + 5`)
-    # value: <cmd>
+    ? def execVow(sourceCode) :any {
+    >     def [reportVow, cmd] := cmdMaker new(sourceCode)
+    >     cmdLoop enqueue(cmd)
+    >     reportVow
+    > }
+    # value: <execVow>
     
-    ? cmdLoop enqueue(cmd)
-    ? 
-    # valuex: 7
-    
-    ? cmdLoop enqueue(cmdMaker new(e`3 _/ 0`))
-    ? 
-    # problemx: <ArithmeticException: BigInteger divide by zero>
-    #           
+    ? def r1 := execVow("2 + 3")
+    # value: <Eventual ref>
     
+    ? r1
+    # value: "# valuex: 5\n\
+    #        \n\
+    #        "
+    
+    ? def epVow := cmdLoop getExitPairVow()
+    # value: <Eventual ref>
+    
+    ? def r2 := execVow("3 _/ 0")
+    # value: <Eventual ref>
+    
+    ? r2
+    # value: "# problem: <ArithmeticException: BigInteger divide by zero>\n\
+    #        \n\
+    #        "
+    
     ? cmdLoop setShowsEStack(true)
-    ? cmdLoop enqueue(cmdMaker new(e`3 _/ 0`))
-    ? 
-    # problemx: <ArithmeticException: BigInteger divide by zero>
-    #           
-    #   3 floorDivide(0)
-    #   e`3 floorDivide(0)` eval([org.erights.e.elang.scope.ScopeImpl@5dffbd])
+    ? def r3 := execVow("3 _/ 0")
+    # value: <Eventual ref>
+    
+    ? r3
+    # value: "# problem: <ArithmeticException: BigInteger divide by zero>\n\
+    #        #\n\
+    #        #   3 floorDivide(0)\n\
+    #        #   e`3 floorDivide(0)` eval([org.erights.e.elang.scope.MutableScope@3aa7d4])\n\
+    #        \n\
+    #        "
+    
+    ? def r4 := execVow("2 +")
+    # value: <Eventual ref>
+    
+    ? r4
+    # value: "# syntax error: Unexpected EOF\n\
+    #        #\n\
+    #        #   <import:org.erights.e.elang.syntax.EParser>(\"2 +\")\n\
+    #        \n\
+    #        "
     
-    ? 
+    ? 
\ No newline at end of file



1.2       +52 -17    e/src/esrc/org/erights/e/elang/cmd/controlLoopMakerAuthor.emaker

Index: controlLoopMakerAuthor.emaker
===================================================================
RCS file: /cvs/e/src/esrc/org/erights/e/elang/cmd/controlLoopMakerAuthor.emaker,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- controlLoopMakerAuthor.emaker	2001/08/16 03:05:37	1.1
+++ controlLoopMakerAuthor.emaker	2001/08/19 06:35:55	1.2
@@ -1,14 +1,38 @@
 def controlLoopMakerAuthor(QueueMaker) :any {
     class controlLoopMaker() :any {
+
+        # Should we block between turns?
         var myShouldBlock := false
+
+        # Is there a 'internalLoop <- ()' in the air?
         var myIsAlarmSet := false
-        # if non-null, we *should* exit
+
+        # A pair of an exit-code and an optional problem.
+        # If non-null, we *should* exit.
         var myOptExitPair := null
-        # if non-null, we *have* exitted
+        def [myExitPairVow, myExitPairResolver] := PromiseMaker()
+
+        # A queue of Runnables to run in order, each in their own
+        # turn.  If null, we *have* exitted.
         var myOptQueue := QueueMaker new()
 
+        var servingTicket := 0
+        var nextTicket := 1
+
+        def myStatusReactors := [] diverge()
+
+        def notifier {
+            match [verb, args] {
+                for reactor in myStatusReactors {
+                    E sendOnly(reactor, verb, args)
+                }
+            }
+        }
+
         def internalLoop
+        def controlLoop
 
+        # Make sure we're going to wake up if we should
         def setAlarm() {
             if (! myIsAlarmSet && ! myShouldBlock && myOptQueue != null) {
                myIsAlarmSet := true
@@ -20,39 +44,51 @@
             myIsAlarmSet := false
             if (myShouldBlock) {
                 # do nothing
+                notifier reactToBlock(servingTicket)
             } else if (myOptExitPair != null) {
                 myOptQueue := null
+                myExitPairResolver resolve(myOptExitPair)
+                notifier reactToExit(servingTicket, myOptExitPair[0], myOptExitPair[1])
             } else if (myOptQueue optDequeue() =~ runnable ? (runnable != null)) {
+                servingTicket += 1
                 try {
                     runnable()
+                    notifier reactToSuccess(servingTicket, myShouldBlock)
                 } catch problem {
-                    myOptExitPair := [-1, problem]
+                    controlLoop exitAtTop(-1, problem)
                 }
                 setAlarm()
             } else {
+                notifier reactToQueueEmpty(servingTicket)
                 # queue is empty, do nothing
             }
         }
 
-        def controlLoop {
+        def bind controlLoop {
             to blockAtTop() {
-                myShouldBlock := true
+                if (myOptExitPair == null) {
+                    # Don't block if we should exit.  We won't execute any more 
+                    # runnables anyway.
+                    myShouldBlock := true
+                }
             }
             to continueAtTop() {
                 myShouldBlock := false
                 setAlarm()
             }
             to waitAtTop(ref) {
-                Ref whenResolved(ref, def _(_){ 
+                controlLoop blockAtTop()
+                def done(_) { 
                     controlLoop continueAtTop()
-                })
+                }
+                Ref whenResolved(ref, done)
             }
             to exitAtTop() {
-                myOptExitPair := [0, null]
-                setAlarm()
+                controlLoop exitAtTop(0, null)
             }
             to exitAtTop(exitCode, optProblem) {
                 myOptExitPair := [exitCode, optProblem]
+                myShouldBlock := false
                 setAlarm()
             }
             to enqueue(runnable) {
@@ -60,20 +96,19 @@
                     myOptQueue enqueue(runnable)
                     setAlarm()
                 }
+                notifier reactToEnqueue(nextTicket)
+                nextTicket += 1
             }
             # Returns a pair of an exit code and an optional problem.
             # Normally, an exit code of zero should have no problem
             # whereas any other exit code should have a problem, but
             # this is not enforced.  XXX It probably should be and 
             # will be enforced.
-            to getOptExitPair() :any {
-                if (myOptQueue == null) {
-                    require(myOptExitPair != null,
-                            thunk{"internal: no exit pair"})
-                    myOptExitPair
-                } else {
-                    null
-                }
+            to getExitPairVow() :any {
+                myExitPairVow
+            }
+            to addStatusReactor(reactor) {
+                myStatusReactors push(reactor)
             }
         }
     }



1.3       +73 -9     e/src/esrc/org/erights/e/elang/cmd/controlLoopMakerAuthor.updoc

Index: controlLoopMakerAuthor.updoc
===================================================================
RCS file: /cvs/e/src/esrc/org/erights/e/elang/cmd/controlLoopMakerAuthor.updoc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- controlLoopMakerAuthor.updoc	2001/08/16 07:05:38	1.2
+++ controlLoopMakerAuthor.updoc	2001/08/19 06:35:55	1.3
@@ -7,27 +7,43 @@
     ? def controlLoopMaker := <cmd:controlLoopMakerAuthor>(QueueMaker)
     # value: <controlLoopMaker>
     
+    ? def reactor {
+    >     match [verb, args] {
+    >         println(`$verb$args`)
+    >     }
+    > }
+    # value: <reactor>
+    
     ? def ctrl := controlLoopMaker new()
-    # value: <controlLoop>
+    # value: <controlLoop_7>
     
+    ? ctrl addStatusReactor(reactor)
     ? ctrl enqueue(thunk{println("foo")})
     ? 
     foo
+    reactToEnqueue[1]
+    reactToSuccess[1, false]
+    reactToQueueEmpty[1]
     ? (ctrl enqueue(thunk{println("bar")})
     >  ctrl blockAtTop()
     >  ctrl enqueue(thunk{println("baz")})
     > )
     ? 
+    reactToEnqueue[2]
+    reactToEnqueue[3]
+    reactToBlock[1]
     ? ctrl continueAtTop()
     ? 
     bar
+    reactToSuccess[2, false]
     baz
+    reactToSuccess[3, false]
+    reactToQueueEmpty[3]
     ? def [p,r] := PromiseMaker()
     # value: [<Eventual ref>, <Open Resolver>]
     
     ? def event() {
     >     println("before")
-    >     ctrl blockAtTop()
     >     println("after")
     >     ctrl enqueue(thunk{println("next")})
     >     ctrl waitAtTop(p)
@@ -38,29 +54,77 @@
     ? 
     before
     after
+    reactToEnqueue[4]
+    reactToEnqueue[5]
+    reactToSuccess[4, true]
+    reactToBlock[4]
     ? 
     ? r resolve(3)
     ? 
     next
-    ? ctrl getOptExitPair()
+    reactToSuccess[5, false]
+    reactToQueueEmpty[5]
+    ? def exitPairVow := ctrl getExitPairVow()
+    # value: <Eventual ref>
+    
+    ? exitPairVow
+    # value: <Eventual ref>
+    
     ? def event2() {
     >     ctrl exitAtTop()
-    >     println(`exit: ${ctrl getOptExitPair()}`)
+    >     println(`exit: ${ctrl getExitPairVow()}`)
     >     ctrl enqueue(thunk{println("already dead")})
     > }
     # value: <event2>
     
     ? ctrl enqueue(event2)
+    ? 
+    exit: <Eventual ref>
+    reactToEnqueue[6]
+    reactToEnqueue[7]
+    reactToSuccess[6, false]
+    reactToExit[6, 0, null]
+    ? 
+    ? exitPairVow
+    # value: [0, null]
+    
+    ? def ctrl3
+    # value: <Eventual ref>
+    
+    ? def event3() {
+    >     println("before")
+    >     println("after")
+    >     ctrl3 enqueue(thunk{println("next")})
+    >     ctrl3 blockAtTop()
+    > }
+    # value: <event3>
+    
+    ? def bind ctrl3 := controlLoopMaker new()
+    # value: <controlLoop_7>
+    
+    ? ctrl3 addStatusReactor(reactor)
+    ? ctrl3 enqueue(event3)
+    ? 
+    before
+    after
+    reactToEnqueue[1]
+    reactToEnqueue[2]
+    reactToSuccess[1, true]
+    reactToBlock[1]
+    ? def exitPairVow3 := ctrl3 getExitPairVow()
+    # value: <Eventual ref>
+    
+    ? exitPairVow3
+    # value: <Eventual ref>
+    
+    ? ctrl3 exitAtTop()
     ? 
-    exit: null
+    reactToExit[1, 0, null]
     ? 
-    ? ctrl getOptExitPair()
+    ? exitPairVow3
     # value: [0, null]
     
     ? 
-
-
-
 
 
 



1.13      +0 -1      e/src/jsrc/net/captp/jcomm/ProxyOutputStream.java

Index: ProxyOutputStream.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/captp/jcomm/ProxyOutputStream.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- ProxyOutputStream.java	2001/08/17 03:11:32	1.12
+++ ProxyOutputStream.java	2001/08/19 06:35:55	1.13
@@ -103,7 +103,6 @@
         if (Ref.isNear(ref)) {
             if (Ref.isPassByProxy(ref)) {
                 return myConn.makeImportingDesc(ref);
-                
             }
             throw new IOException("the " + clazz +
                            " is neither PassByConstruction nor PassByProxy");



1.62      +5 -5      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.61
retrieving revision 1.62
diff -u -r1.61 -r1.62
--- ScopeSetup.java	2001/08/05 07:01:24	1.61
+++ ScopeSetup.java	2001/08/19 06:35:55	1.62
@@ -245,11 +245,11 @@
      * If the interp isn't resolved yet, the props must be provided 
      * explicitly.
      */
-    static /*package*/ Scope privileged(boolean interactive,
-                                        TextWriter stdout,
-                                        TextWriter stderr,
-                                        ConstMap props,
-                                        Object interpPromise)
+    static public Scope privileged(boolean interactive,
+                                   TextWriter stdout,
+                                   TextWriter stderr,
+                                   ConstMap props,
+                                   Object interpPromise)
     {
         Scope univ = universal();
 



1.24      +5 -3      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.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- ParseNode.java	2001/07/14 12:57:23	1.23
+++ ParseNode.java	2001/08/19 06:35:55	1.24
@@ -204,12 +204,14 @@
      * For VisualAge
      */
     public String toString() {
-        StringWriter strWriter = new StringWriter();
+        Object[] pair = TextWriter.makeBufferingPair();
+        TextWriter tw = (TextWriter)pair[0];
+        StringBuffer sb = (StringBuffer)pair[1];
         try {
-            subPrintOn(new TextWriter(strWriter), PR_START);
+            subPrintOn(tw, PR_START);
         } catch (IOException iox) {
             throw ThrowableSugar.backtrace(iox, "in ParseNode.toString()");
         }
-        return strWriter.getBuffer().toString();
+        return sb.toString();
     }        
 }



1.29      +12 -0     e/src/jsrc/org/erights/e/elib/base/TextWriter.java

Index: TextWriter.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/TextWriter.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- TextWriter.java	2001/07/16 10:42:48	1.28
+++ TextWriter.java	2001/08/19 06:35:55	1.29
@@ -20,6 +20,7 @@
 */
 import java.io.FilterWriter;
 import java.io.IOException;
+import java.io.StringWriter;
 import java.io.Writer;
 import org.erights.e.elib.prim.E;
 import org.erights.e.elib.ref.Ref;
@@ -49,6 +50,17 @@
     private boolean myAutoflush;
     private boolean myCloses;
     private CycleBreaker myCycleBreaker;
+    
+    /**
+     * Returns a pair of a TextWriter and the StringBuffer it writes into.
+     */
+    static public Object[] makeBufferingPair() {
+        StringWriter sw = new StringWriter();
+        TextWriter tw = new TextWriter(sw);
+        StringBuffer sb = sw.getBuffer();
+        Object[] result = { tw, sb };
+        return result;
+    }
 
     /**
      * Initial newline defaults to "\n".  autoflush and closes



1.13      +1 -0      e/src/jsrc/org/erights/e/elib/prim/StaticMaker.java

Index: StaticMaker.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/StaticMaker.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- StaticMaker.java	2001/08/17 05:48:58	1.12
+++ StaticMaker.java	2001/08/19 06:35:55	1.13
@@ -77,6 +77,7 @@
         
         "org.erights.e.elib.base.MessageDesc",
         "org.erights.e.elib.base.ParamDesc",
+        "org.erights.e.elib.base.TextWriter",
         "org.erights.e.elib.quasi.FirstCharSplitter",
         "org.erights.e.elib.quasi.Identifiers",
         "org.erights.e.elib.quasi.Substituter",



1.22      +23 -13    e/src/jsrc/org/erights/e/elib/ref/Ref.java

Index: Ref.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/ref/Ref.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- Ref.java	2001/08/18 05:19:38	1.21
+++ Ref.java	2001/08/19 06:35:55	1.22
@@ -30,6 +30,7 @@
 import org.erights.e.elib.sealing.SealedBox;
 import org.erights.e.elib.serial.PassByConstruction;
 import org.erights.e.elib.serial.PassByProxy;
+import org.erights.e.elib.serial.Persistent;
 import org.erights.e.elib.tables.Equalizer;
 import org.erights.e.elib.tables.FlexList;
 import org.erights.e.elib.tables.NotSettledException;
@@ -472,15 +473,32 @@
     }
     
     /**
-     *
+     * Can this reference be saved and restored with a {@link 
+     * org.erights.e.elib.serial.Serializer} and an {@link 
+     * org.erights.e.elib.serial.Unserializer}?
+     * <p>
+     * The cases are <ul>
+     * <li>Broken references are persistent.
+     * <li><code>null</code> is persistent.
+     * <li>Instances of {@link Persistent} are persistent.
+     * <li>Arrays are persistent.
+     * <li>Instances of any {@link Persistent#HONORARY} classes are 
+     *     persistent. 
+     * <li>A Far reference (a Resolved Eventual reference) is not persistent, 
+     *     but is saved as a DisconnectedRef (a kind of BrokenRef) that 
+     *     maintains the far reference's sameness identity. 
+     * <li>All other non-persistent references, including all Promises 
+     *     (Unresolved references) are saved as UnconnectedRefs (Broken 
+     *     references without a sameness identity). 
+     * <ul>
      */
-    /*static public boolean isPersistent(Object ref) {
+    static public boolean isPersistent(Object ref) {
         ref = resolution(ref);
-        if (! isNear(ref)) {
+        if (isEventual(ref)) {
             return false;
         }
         if (null == ref) {
-            //null is trivially PassByCopy
+            //null is trivially Persistent
             return true;
         }
         Class clazz = ref.getClass();
@@ -494,15 +512,7 @@
         }
         return Persistent.HONORARY.has(clazz);
     }        
-    */
-    /**
-     * Being PassByCopy == being Selfless && being PassByConstruction. <p>
-     */
-    /*static public boolean isPassByCopy(Object ref) {
-        return isSelfless(ref) && isPBC(ref);
-    }
-    */
-
+    
     /**
      * If two object references are the same(), they are indistinguishable up 
      * to brokeness XXX no longer true, changed to designational equivalence, 



1.10      +3 -8      e/src/jsrc/org/erights/e/elib/serial/PassByConstruction.java

Index: PassByConstruction.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/serial/PassByConstruction.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- PassByConstruction.java	2001/08/17 20:59:26	1.9
+++ PassByConstruction.java	2001/08/19 06:35:55	1.10
@@ -25,6 +25,9 @@
 /**
  * Marker interface that makes objects passable-by-construction via
  * CapTP.
+ *
+ * @author Mark S. Miller
+ * @author Terry Stanley
  */
 public interface PassByConstruction extends Serializable {
 
@@ -59,14 +62,6 @@
         //of the stack trace, and we currently have no way to enforce the 
         //transitive adherence to any rules by Throwable subclasses.
         "java.lang.Throwable",
-        
-        //We'd like these to be (at least honorarily) Selfless, and therefore 
-        //PassByCopy, but they don't implement their own equals() and 
-        //hashCode(), and there doesn't seem to be any generic way to get 
-        //their contents and restore them from their contents.  However, 
-        //KeySpec looks like a hopeful solution someday.
-        "java.security.Key",
-        "java.security.KeyPair",
     };
 
     /**



1.2       +54 -1     e/src/jsrc/org/erights/e/elib/serial/Persistent.java

Index: Persistent.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/serial/Persistent.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Persistent.java	2000/09/07 04:20:30	1.1
+++ Persistent.java	2001/08/19 06:35:56	1.2
@@ -18,10 +18,63 @@
 
 Contributor(s): ______________________________________.
 */
+
 import java.io.Serializable;
+import org.erights.e.elib.tables.ConstSubclassSet;
 
 /**
- * Marker interface that makes objects persistifiable.
+ * Marker interface that enables object to be saved and restored using the 
+ * {@link Serializer} and {@link Unserializer}.
+ *
+ * @author Mark S. Miller
  */
 public interface Persistent extends Serializable {
+    
+    /**
+     * List of Java library classes to be considered persistent. 
+     * <p>
+     * This is because, since they are JavaSoft's, we obviously can't go back 
+     * and modify them to implement the Persistent interface, but we equally 
+     * obviously want people to be able to use them as if we had. 
+     */
+    static final String HONORED_NAMES[] = {
+        //also PBC, Transparent, & Selfless, and so PassByCopy
+        "java.lang.Boolean",
+        "java.lang.Character",
+        "java.lang.String",
+
+        //also PBC, Transparent, & Selfless, and so PassByCopy
+        "java.lang.Float",
+        "java.lang.Double",
+        "java.lang.Byte",
+        "java.lang.Short",
+        "java.lang.Integer",
+        "java.lang.Long",
+        "java.math.BigInteger",
+        
+        //also PBC & Selfless, but not Transparent or PassByCopy
+        "net.captp.api.SturdyRef",
+
+        //We would like Throwable to be transitively PassByCopy, but it 
+        //doesn't provide its own equals() and hashCode(), so it can't be 
+        //made even honorarily Selfless, it's not really transparent because 
+        //of the stack trace, and we currently have no way to enforce the 
+        //transitive adherence to any rules by Throwable subclasses.
+        "java.lang.Throwable",
+        
+        //We'd like these to be (at least honorarily) Selfless, and therefore 
+        //PassByCopy, but they don't implement their own equals() and 
+        //hashCode(), and there doesn't seem to be any generic way to get 
+        //their contents and restore them from their contents.  However, 
+        //KeySpec looks like a hopeful solution someday.
+        "java.security.Key",
+        "java.security.KeyPair",
+    };
+
+    /**
+     * HONORARY (effectively) contains all the classes named in HONORED_NAMES
+     * and all their subclasses.
+     */
+    static public final ConstSubclassSet HONORARY
+        = ConstSubclassSet.make(HONORED_NAMES);
 }



1.7       +4 -3      e/src/jsrc/org/erights/e/elib/serial/Serializer.java

Index: Serializer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/serial/Serializer.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Serializer.java	2001/08/18 05:19:38	1.6
+++ Serializer.java	2001/08/19 06:35:56	1.7
@@ -83,14 +83,15 @@
     }
     
     /**
-     * Just applies the replacer I was constructed with.
+     * Just applies the replacer I was constructed with, and insists that the 
+     * resulting object {@link Ref#isPersistent(Object)}.
      */
     protected Object replaceObject(Object obj) throws IOException {
         obj = Ref.resolution(obj);
         obj = myReplacer.run(obj);
         obj = Ref.resolution(obj);
-        if (! Ref.isPBC(obj)) {
-            throw new RuntimeException("not pbc: " + obj);
+        if (! Ref.isPersistent(obj)) {
+            throw new RuntimeException("not persistent: " + obj);
         }
         return obj;
     }



1.6       +4 -3      e/src/jsrc/org/erights/e/elib/serial/Unserializer.java

Index: Unserializer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/serial/Unserializer.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Unserializer.java	2001/08/17 20:59:26	1.5
+++ Unserializer.java	2001/08/19 06:35:56	1.6
@@ -82,12 +82,13 @@
                               
     
     /**
-     * Just applies the resolver I was constructed with.
+     * Just insists that obj {@link Ref#isPersistent(Object)}, and applies 
+     * the resolver I was constructed with. 
      */
     protected Object resolveObject(Object obj) throws IOException {
         obj = Ref.resolution(obj);
-        if (! Ref.isPBC(obj)) {
-            throw new RuntimeException("not pbc: " + obj);
+        if (! Ref.isPersistent(obj)) {
+            throw new RuntimeException("not persistent: " + obj);
         }
         obj = myResolver.run(obj);
         obj = Ref.resolution(obj);



1.31      +5 -3      e/src/jsrc/org/erights/e/ui/elmer/EInterpAdapter.java

Index: EInterpAdapter.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/ui/elmer/EInterpAdapter.java,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- EInterpAdapter.java	2001/08/18 05:19:38	1.30
+++ EInterpAdapter.java	2001/08/19 06:35:56	1.31
@@ -62,9 +62,11 @@
     public EInterpAdapter(JedMain elmer) {
         myElmer = elmer;
         myTextArea = elmer.textArea();
-        StringWriter writer = new StringWriter();
-        myOutBuffer = writer.getBuffer();
-        myOuts = new TextWriter(writer);
+
+        Object[] pair = TextWriter.makeBufferingPair();
+        myOuts = (TextWriter)pair[0];
+        myOutBuffer = (StringBuffer)pair[1];
+
         //XXX If used, should be passed in to the constructor
         //TextWriter errs = new TextWriter(PrintStreamWriter.err());